hamburger icon "
curl Javascript PHP Python Java Ruby C#

Getting Started

Asana’s API and you

Collaboration across teams and tools works best when everyone stays in sync and processes flow easily and without friction. This is why we have Asana's API: it's a platform to ensure all of your information is up to date and that your teams stay efficient and in the loop.

Asana’s API provides a means for software and scripts to read information from inside Asana, input information from outside Asana, and automatically react when things change. This can include:

The role of Asana's platform is to allow Asana to meet your team where you are and how you work. Asana is built to be flexible and powerful, to be intuitive enough for all teams to adopt and maintain clarity on who is doing what by when. Asana’s platform enables you to specialize this flexibility to maximize efficiency. Here are some ideas for what you can build:

Doing repetitive work

Integrations and bots are great for making sure that repetitive tasks are always taken care of. Running a script with Asana's API can quickly take care of work like moving cards between board columns, setting assignees or due dates based on the state of the task, or asking that all custom fields are set before work can begin on a task. This can save time and overhead when trying to keep your projects clear and correct.

Reacting to changes

Workflows with Asana often have a "when this task changes, do something" feel. An example is moving tasks between projects based on subtasks: if one team completes a subtask, move the parent task to the next team's project. Integrations can be built to respond in near-real time to changes in Asana to move work forward to the next step.

Generating reports

Fetching the state of the tasks in a project or for your teammates can unlock the ability to create simple - or complex - metrics around how you are progressing. How many open tasks are there in the project? Who has the most tasks assigned? How often does the due date of each task get shifted back? Our platform enables pulling of data from Asana to make customized metrics to track your work.

Keeping in sync

Teams frequently use a multitude of software tools to accomplish work, from email to asset management to file storage. These specialized tools are often used with colleagues who don't track their work with Asana; and even if they do, keeping all of your tools in sync makes the transitions between tools straightforward to minimize work about work.

Some of our integration partners, like Tray.io, Unito, and Zapier, offer syncing solutions out of the box with common workplace tools, or you could build your own solution in cases where you need more flexibility, such as when connecting to customized or internally-built software.

Capturing work

Asana is built for teamwork and knowing who is doing what by when. Having an easy way to capture information in Asana makes it less likely that work will slip through the cracks. For example, when communicating with people who work in other companies who aren't members of your Asana organization, an integration like we built for Gmail lets you create follow-up tasks with just a few clicks.

Getting information into Asana in a quick and easy way is important for ensuring that you don’t drop the ball. Asana’s platform is a great way to pull information from many channels into Asana with minimum hassle.

Extending Asana

Asana is built to be a tool that works well for all teams, so we build features into our core product that aren't overly opinionated about how you get work done. At the same time, there is opportunity for teams to use Asana in a specialized way or with specific additional features. When there are features that you'd like Asana to have, our platform is a resource to make them happen. As a matter of fact, some of our more successful integrations like Instagantt exist purely to provide additional features to Asana.

Customizing workflows

Integrations or scripts work great to maintain a custom workflow, saving a team member from having to continually pay attention to the state of tasks in Asana.

Whether it's ensuring that custom fields are filled out, tasks are completed, tasks live in the correct board-view column, or automatically assigning tasks at certain stages in your process, integrations can react to changes in Asana to ensure that everyone is up to date. When processes mature around how you get work done, it's a great time to use Asana's platform to make sure everything stays consistent and clear.

Check out some examples of integrations we've built on Asana below:

Learn more or submit an app you've built

Read more on how to get started building on Asana or submit an app to add to our apps page.

Q&A Response

Asana's API enables customization and automation of your organization’s workflow through scripts built to specialize your use of Asana. Using Asana to track your work and leveraging Asana’s API to automate your processes is a powerful combination which can make your team much more efficient. Here's one example of how we do it at Asana.

Tracking timely responses to support questions

Asana’s developer relations team manages technical support for our API through a number of channels: support tickets, questions about our API and integrations forwarded on from our colleagues, the Asana Community's Developer category, Stack Overflow, pull requests and bug reports from open-source GitHub projects like our client libraries, and more. Staying on top of all of these channels can be daunting, but we want our users to reach us however works best for them. At the same time, we want to isolate the noisiness of incoming requests for our colleagues at Asana who are involved with only one channel.

Additionally, the management of the question and answer process, triaging the incoming requests, troubleshooting with our engineers, and measuring our response performance are all internal processes. Even if we have a workflow in place to support our developer relations team, we want the experience for other teams to be easy and lightweight. We want to ensure our coworkers do the right things by default without hindering the consistency of our work and our ability to track progress.

Our solution: automation and reporting through our API to provide consistent management of the whole process.

To do this, we wrote an integration with the following goals in mind:

The script we built does the following for us:

  1. Integrate with external sources to put incoming questions into Asana, one project per channel.
  2. Add question tasks from each incoming project into a single combined project.
  3. Acknowledge a question has been received and begin tracking response times.
  4. Upon first response, complete a task to signal relevant followers that we've reached out.

Maintain focus

We use webhooks to get notified in near-real time when new tasks are created in any of several Asana projects, one per incoming channel. Some of these projects are automatically synced with outside sources, others are available for our coworkers to create tasks in. Keeping tasks in their source channel helps keep us organized for where to go to respond. These projects are what our colleagues follow in order to remain focused on their own channels.

Our script responds to these webhook notifications from each project by adding these tasks into a single "Developer Questions" project. Our developer relations team can then see all outstanding questions about our API in a single place. This is a key part of hitting our service level agreement (SLA) goals: not having to cycle through many projects and channels to see how we're progressing.

Ensure timely responses

Once a question gets added to our Developer Questions project, our integration creates a subtask on it. This signals to our colleagues that we have received the question and will begin to triage and investigate. The subtask is completed when we first respond to our users to inform them that we're investigating. Completion of the question task itself signals that we've achieved a resolution for the person who reached out to us.

Track progress

Our script can generate a simple report to see which questions are still open, how long they’ve been open, and how much time we have left to answer before we miss our service level agreement limits. A simple webpage that the integration creates enables a high level view of what's still in progress and how timely we've been in the past.

Keep the process moving, automatically

Our integration also helps automate some of the routine steps to ensure questions get answered. After a task gets triaged for priority, our integration sets an appropriate due date. It can also set an assignee and followers based on current workload and by matching certain keywords in the task description. If the task approaches its due date and it has not received a response, the script comments on the task to alert us that the question is about to reach our SLA limit. This helps us keep the right people in the loop with minimal overhead and maximum clarity of what needs to be done by when.

By managing this routine and specialized workflow with automation through Asana’s API, our team is more efficient, more effective, and less likely to make a mistake. We know how responsive we've been and can see how we're doing at any time. We're better able to minimize the number of questions which slip through the cracks. The result is better support for outside developers and increased focus on core work, not work about work.

Over time, we've continuously tweaked how our integration behaves to evolve our process, empowering us to adjust and iterate our approach. This is one of the key opportunities that Asana's API provides: ownership and control over how work gets done. Incremental improvements provide the chance to try out new workflows and settle on one that works well for everyone, leading to a more consistent and customized experience of using Asana.

To get started, check out our quick start page for an overview of Asana's API. For support or to generate ideas of how your team can work more effectively with Asana, head to the Asana Community to chat with Asana team members and users!

Bot examples

Reminder bot

Even the most conscientious and best-intentioned teammate can get overloaded and occasionally forget a task. For project managers, team leads, or coordinators, it can be draining to check-in on everyone to make sure that everything is going according to schedule. How can you stay on track and minimize the work-about-work?

Instead of continually reminding teammates to stay focused, use Asana’s API to create a bot for automatic reminders (a bot is a script that performs a task automatically). In this case, a "ping bot" takes action when due dates are approaching (or for any other specified trigger). This can act as a more intelligent version of the reminders that Asana already sends when due dates approach. For example, this persistent friend could comment with reminders further in advance, ask assignees or followers to take some action like setting a custom field, re-assign the work, and/or push out due dates. With a bot taking care of the schedule and reminders, people can spend their time on the work that needs human attention, like ideation and feedback.

Recruiting bot

At Asana, we use a bot to help automate the job application process for engineering candidates. When candidates complete a coding test, the test needs to get graded in a timely manner to keep the interview process on track and to keep the candidate from feeling stranded or forgotten about.

Once candidates have submitted their coding test, a bot uses the Asana API to assign the test to a grader based on specific criteria tracked in Asana, such as their preferred programming languages and number of previous evaluations. Graders are given x days to grade tests (the bot takes into account when graders are out of office). If tests have not been graded by the due date, graders are pinged by the bot with a comment on the task to either grade the test or re-assign it to someone else. After x days, the bot automatically re-assigns the test to the next grader to keep the process moving.

Bugs bot

Our engineering teams handle triaging bug reports by creating a task in a "Bugs" project. A bot then adds the project manager of the relevant team in Asana as a follower, moves the task into a "needs triage" section, and requests assistance. The project manager can then evaluate the bug and triage it.

Since the evaluation of the severity of the bug is important for understanding how urgent the fix is, Bugs Bot will remain persistent, commenting every few days until the task has been moved out of the triage section and into a section of the relevant priority. This process ensures that we're aware of the impact of bugs and helps us avoid severe bugs slipping through the cracks.

Quick Start

If you’re new to developing on APIs, this is a great place to start. You’ll learn in this guide how to make the simplest Asana API request -- getting your user information.

To get started, be sure you are logged into Asana. Next, go to this URL: https://app.asana.com/api/1.0/users/me

Congratulations! You’ve just made your first Asana API request.

Let’s unpack what just happened. The base URL for all requests to the Asana API is https://app.asana.com/api/1.0. We want information about users, so we go down a level to the https://app.asana.com/api/1.0/users resource. Within the set of all users in Asana, We’re specifically looking to get information about our own account, so we get more specific by adding /me to get https://app.asana.com/api/1.0/users/me. The /me part would ordinarily be an identifier (a long number) or email address of the user, but we've created this shorthand for getting the current user of Asana's API, whomever that may be. Put it together and you have the above path to get your user information from Asana.

Since every API request you make will start with the same base URL ('https://app.asana.com/api/1.0'), we'll just talk about what comes next in the URL -- which is often referred to as a 'resource' or 'path'. For instance, when we say /users/me it's actually shorthand for the entire URL which would be https://app.asana.com/api/1.0/users/me.

After requesting information from the API, you will receive a resposne in JSON format, which can be read and understood by both humans and computers. It's structured in a particular way so programs can rely on a consistent format for the data.

Our API is documented for what resources are available and what sort of return data to expect. For example, here are the docs for the /users endpoint which we just called. This is where you can discover what's possible with our API.

Now, let’s make the same call to /users/me more like software would. Before we do so, we’ll need to get access outside of your web browser to the API.

Authentication Quick Start

Similarly to entering your username/password into a website or logging into Asana with Google, when you access your Asana data via the API you need to authenticate. In the above example, you were already logged into Asana in your browser so you were able to authenticate to the API with credentials stored by your browser.

If you want to write a script that interacts with the Asana API, the easiest method is to get a Personal Access Token (PAT), which you can think of as your unique password for accessing the API.

Getting a Personal Access Token (PAT)

  1. Open the Developer App Management page by using this permalink or following these steps:

* From within Asana, click your profile photo from the top bar and select "My Profile Settings"

* Click the "Apps" tab

* Click "Manage Developer Apps"

  1. Click "+ Create New Personal Access Token"

  2. Type a description of what you’ll use the Personal Access Token for.

  3. Click "Create"

  4. Copy your token. You will only see this one time, but you can always create another PAT later.

Note: treat your PAT like you would a password. Do not share it or display it online.

Accessing the API in the Terminal

We’ll use cURL, a command line[^1] program to make HTTP requests. MacOS and many Linux distributions have cURL pre-installed, and it’s available for download on Windows and many other operating systems. If you’re curious, you can learn more about cURL in its own documentation.

Let’s do this:

  1. Open a terminal (instructions for Mac and Windows)

  2. Copy/paste the following cURL request (make sure to enter your personal access token instead of the placeholder after the word "Bearer" below, or else you'll get a "Not Authorized" message):

    curl -H "Authorization: Bearer 0/123456789abcdef" https://app.asana.com/api/1.0/users/me

  3. Press Enter

Nice work! You just wrote a cURL command.

In our API documentation, we will often write examples as cURL commands since it's a middle-of-the-road approach to accessing our API: more flexible than using a browser, but user-friendly enough to be quick and easy to do.

You’re ready to start coding!

Asana has client libraries in several popular coding languages. Using these libraries has several advantages (like managing authorization and retrying errors) that make them a good place to go from here. Let’s take a look at making the same /users/me request in Python, JavaScript, and Ruby (feel free to skip ahead to your favorite of the three languages).

Client Examples

Python (v2.x)

To get started, run pip install asana or follow the detailed installation instructions on the GitHub page for the Python client library.

Once it’s installed, open your favorite text editor and we’ll code a GET request to /users/me - the same request as above, but in Python.

import asana

# replace with your personal access token. 
personal_access_token = '0/123456789....'

# Construct an Asana client
client = asana.Client.access_token(personal_access_token)
# Set things up to send the name of this script to us to show that you succeeded! This is optional.
client.options['client_name'] = "hello_world_python"

# Get your user info
me = client.users.me()

# Print out your information
print "Hello world! " + "My name is " + me['name'] + " and I my primary Asana workspace is " + me['workspaces'][0]['name'] + "."

Save this file as something descriptive like "hello_world.py"

To run this script in your console, pass it as an argument to the python interpreter, i.e. python hello_world.py from the same directory as the file. You should see the message we wrote above with your user information.

As an aside, for clarity python-asana will also work with Python 3.x (with small changes to the above example to make it compatible.)

All of the built-in functions can be found in the /gen folder of the client library.

You can see a variant of this script, and other useful Asana API scripts, in our open-source Github examples repository

JavaScript

To get started, npm install asana or follow the detailed installation instructions on the GitHub page for the Node client library.

Once it’s installed, open your favorite text editor and we’ll code a GET request to /users/me. - the same request as above, but in JavaScript.

var asana = require('asana');

// replace with your personal access token. 
var personalAccessToken = '0/123456789....';

// Construct an Asana client
var client = asana.Client.create().useAccessToken(personalAccessToken);

// Get your user info
client.users.me()
  .then(function(me) {
    // Print out your information
    console.log('Hello world! ' + 'My name is ' + me.name + ' and my primary Asana workspace is ' + me.workspaces[0].name + '.');
});

Save this file as something descriptive like "hello_world.js"

To run this script in your console, pass it as an argument to the node interpreter, i.e. node hello_world.py from the same directory as the file. You should see the message we wrote above with your user information.

All of the built-in functions can be found in the /gen folder of the client library.

You can see a variant of this script, and other useful Asana API scripts, in our open-source Github examples repository

Ruby

To get started, gem install asana or follow the detailed installation instructions on the GitHub page for the Ruby client library.

Once it’s installed, open your favorite text editor and we’ll code a GET request to /users/me.

require 'asana'

# replace with your personal access token. 

personal_access_token = '0/123456789....'

client = Asana::Client.new do |c|

  c.authentication :access_token, personal_access_token

end

me = client.users.me

puts "Hello world! " + "My name is " + me.name + " and I my primary Asana workspace is " + me.workspaces[0].name + "."

Save this file as something descriptive like "hello_world.rb"

To run this script in your console, pass it as an argument to the ruby interpreter, i.e. ruby hello_world.rb from the same directory as the file. You should see the message we wrote above with your user information.

All of the built-in methods can be found in the /resources folder of the client library.

You can see a variant of this script, and other useful Asana API scripts, in our open-source Github examples repository

Congratulations!

You’ve learned three ways to access the Asana API. If you need inspiration of what to build on the Asana API, take a look at these common use cases. If you get stuck, checkout the API section of Asana community. Happy coding!

[^1]: What is a "terminal"? When you double-click an icon on your computer, there is a special application that's in charge of launching other applications. On MacOSX, this program is called "Finder", and on Windows it's called "Windows Explorer". A terminal app is a similar app that launches other applications, but rather than double clicking an icon, you type commands into a text-based window.

Official Client Libraries

Asana is committed to making the developer experience as smooth as possible. Part of this effort is providing high-quality libraries you can use to access the API. The available libraries are listed below, and more are in development. If you don't see what you need, check the open-source community for your platform, and let us know that you'd like to find one here!

JavaScript (Node)

For use in the Node server-side JavaScript runtime.

Links: GitHub

Installation: npm install asana

JavaScript (Browser)

This is built from the Node library above, so you get the exact same interface.

Links: GitHub

Installation: Visit the releases page to download the latest full or minified JS bundle, then include the script in your web page.

Python

Links: GitHub

Installation: pip install asana

Ruby

Links: GitHub

Installation: gem install asana

Java

Links: GitHub

Installation: If you use Maven for dependency management simply include the following in your pom.xml.

com.asana asana 0.6.0

PHP

Links: GitHub

Installation: If you use Composer to manage dependencies you can include the "asana/asana" package as a dependency.

"require": { "asana/asana": "^0.1.2" }

Basic Concepts

Introduction

The Asana API is a RESTful interface, providing programmatic access to much of the data in the system. It provides predictable URLs for accessing resources, and uses built-in HTTP features to receive commands and return responses. This makes it easy to communicate with from a wide variety of environments, from command-line utilities to gadgets to the browser URL bar itself.

The API accepts JSON or form-encoded content in requests and returns JSON content in all of its responses, including errors. Only the UTF-8 character encoding is supported for both requests and responses.

Notes on Pagination

Pagination is an important concept when working with queries for multiple objects. Requests with large result sets may timeout or be truncated; therefore, pagination is strongly encouraged to ensure both you and your users have the best experience when using the Asana API.

Happy coding!

Authentication Basics

Asana supports a few methods of authenticating with the API.

OAuth

Most of the time, OAuth is the preferred method of authentication for developers, users, and Asana as a platform. If you're new to OAuth, take a moment to learn about it here. It's not as scary as you might think!

In addition to learning about how to use OAuth on the Asana platform here, feel free to take a look at the official OAuth spec!

At its core, OAuth is a mechanism for applications to access the Asana API on behalf of a user without the application having access to the username and password. Instead, apps get a token which they can use with their own application credentials to make API calls.

What is OAuth?

If you're using a library to handle this or already understand OAuth and have registered an OAuth application, you may want to skip ahead to the quick reference.

  1. If you have not already, you will need to register an application. Take note of the client ID, an application's username, and the client secret, an application's password (protect it like one)!

  2. A user will arrive at your application and click a button that says "Connect with Asana."

  3. This takes the customer to the User Authorization Endpoint, which displays a page asking the user if they would like to grant access to your third-party application.

  4. If the customer clicks "Allow", they are redirected back to the application, bringing along a special code as a query parameter. (We are assuming the Authorization Code Grant flow, which is the most common.)

  5. The application can now use the Token Exchange Endpoint to exchange the code, together with the Client Secret, for a Bearer Token (which lasts an hour) and a Refresh Token (which can be used to fetch new Bearer Tokens when the current one expires).

  6. The application can make requests of the API using this Bearer Token for the next hour.

  7. Once the Bearer Token expires, the application can again use the Token Exchange Endpoint to exchange the Refresh Token for a new Bearer Token. (This can be repeated for as long as the user has authorized the application.)

This is just one example using the Authorization Code Grant - applications that run entirely in the browser would generally use the Implicit Grant flow instead.

We definitely recommend using a library to take care of the nitty-gritty of OAuth, but hopefully this helps demystify the process somewhat.

Register an Application

You must first register your application with Asana to receive a client ID and client secret. Fortunately, this process is fast and easy: visit your Account Settings dialog, click the Apps tab, and "Add New Application".

You must supply your new application with:

Note that all of these attributes can be changed later, so don't worry too much right away.

Once you have created an app, the details view will include a Client ID, needed to uniquely identify your app to the Asana API, as well as a Client Secret.

Note Your Client Secret is a secret, it should never be shared with anyone or checked into source code that others could gain access to.

Quick Reference

User Authorization Endpoint

Request

Your app redirects the user to https://app.asana.com/-/oauth_authorize, passing parameters along as a standard query string:

Parameter Description
client_id required The Client ID uniquely identifies the application making the request.
redirect_uri required The URI to redirect to on success or error. This must match the Redirect URL specified in the application settings.
response_type required Must be one of code, token, id_token, or the space-delimited combination token id_token.
state required Encodes state of the app, which will be returned verbatim in the response and can be used to match the response up to a given request.
scope optional A space-delimited set of one or more scopes to get the user's permission to access. Defauts to the default OAuth scope if no scopes are specified.

Response

If either the client_id or redirect_uri do not match, the user will simply see a plain-text error. Otherwise, all errors will be sent back to the redirect_uri specified.

The user then sees a screen giving them the opportunity to accept or reject the request for authorization. In either case, the user will be redirected back to the redirect_uri.

If using the response_type=code, your app will receive the following parameters in the query string on successful authorization. If using the response_type=token, these parameters will appear in the URL fragment (the bit following the #):

Parameter Description
code If response_type=code in the request, this is the code your app can exchange for a token
token If response_type=token in the request, this is the token your app can use to make requests of the API
state The state parameter that was sent with the authorizing request

OAuth Scopes

The Asana API supports a small set of OAuth scopes you can request using the scope parameter during the user authorization step of your authentication flow. Multiple scopes can be requested at once as a space-delimited list of scopes. An exhaustive list of the supported scopes is provided here:

Scope Access provided
default Provides access to all endpoints documented in our API reference. If no scopes are requested, this scope is assumed by default.
openid Provides access to OpenID Connect ID tokens and the OpenID Connect user info endpoint.
email Provides access to the user's email through the OpenID Connect user info endpoint.
profile Provides access to the user's name and profile photo through the OpenID Connect user info endpoint.

Token Exchange Endpoint

Request

If your app received a code from the authorization endpoint, it can now be exchanged for a proper token, optionally including a refresh_token, which can be used to request new tokens when the current one expires without needing to redirect or reauthorize the user.

Your app should make a POST request to https://app.asana.com/-/oauth_token, passing the parameters as part of a standard form-encoded post body.

Parameter Description
grant_type required One of authorization_code or refresh_token. See below for more details.
client_id required The Client ID uniquely identifies the application making the request.
client_secret required The Client Secret belonging to the app, found in the details pane of the developer console.
redirect_uri required Must match the redirect_uri specified in the original request.
code sometimes required If grant_type=authorization_code this is the code you are exchanging for an authorization token.
refresh_token sometimes required If grant_type=refresh_token this is the refresh token you are using to be granted a new access token.

The token exchange endpoint is used to exchange a code or refresh token for an access token.

Response

In the response, you will receive a JSON payload with the following parameters:

Parameter Description
access_token The token to use in future requests against the API
expires_in The number of seconds the token is valid, typically 3600 (one hour)
token_type The type of token, in our case, bearer
refresh_token If exchanging a code, a long-lived token that can be used to get new access tokens when old ones expire.
data A JSON object encoding a few key fields about the logged-in user, currently id, name, and email.

Authorization Code Grant

To implement the Authorization Code Grant flow (the most typical flow for most applications), there are three steps:

  1. Send the user to the authorization endpoint so that they can approve access of your app to their Asana account

    # Send the user to the authorization endpoint. Newlines inserted for readability https://app.asana.com/-/oauth_authorize? client_id=123& redirect_uri=https://myapp.com/oauth &response_type=code &state=somerandomstate

  2. Receive a redirect back from the authorization endpoint with a code embedded in the parameters

    # After the user authenticates they will redirected back to your app with a code for your app to exchange. # Newlines inserted for readability https://myapp.com/oauth? code=0%2F817a776a358a5d8d89988562d2b3dc8f& state=somerandomstate

  3. Exchange the code for a token via the token exchange endpoint

The token that you have at the end can be used to make calls to the Asana API on the user's behalf.

Implicit Grant

The Implicit Grant flow is suitable for in-browser web apps written in JavaScript or other applications that cannot securely make the POST request containing the client secret to the authorization server without exposing that secret to the user or others. To implement this flow, there are only two steps:

  1. Redirect a user to the authorization endpoint so that they can approve access of your app to their Asana account

    # Send the user to the authorization endpoint. Newlines inserted for readability https://app.asana.com/-/oauth_authorize? client_id=123& redirect_uri=https://myapp.com/oauth& response_type=token& state=somerandomstate

  2. Receive a redirect back from the authorization endpoint with a token embedded in the fragment portion (the bit following the #) of the URL.

    # After the user authenticates they will redirected back to your app with a short-lived access token. https://myapp.com/auth# access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRob3JpemF0aW9uIjo0NDMxMDYwMjQwODA0Niwic2NvcGUiOiIiLCJpYXQiOjE0Mzg4OTExODEsImV4cCI6MTQzODg5NDc4MX0.kVm8MWD8ahU4hMxT7B7ZrsgAEAw5ebb1yknXlskGfeM& token_type=bearer& expires_in=3600& data=& state=somerandomstate

This token can then be used to access the API, in this case typically using CORS.

Secure Redirect Endpoint

As the redirect from the authorization endpoint in either grant procedure contains a code that is secret between Asana's authorization servers and your application, this response should not occur in plaintext over an unencrypted http connection. Asana is deprecating this behavior. We're enforcing the use of https redirect endpoints for new application registrations, and will soon stop calling back to http apps during the authorization process.

For non-production or personal use, you may wish to check out stunnel, which can act as a proxy to receive an encrypted connection, decrypt it, and forward it on to your application. For development work, you may wish to create a self-signed SSL/TLS certificate for use with your web server; for production work we recommend purchasing a certificate from a certificate authority. A short summary of the steps for each of these processes can be read here.

Your application will need to be configured to accept SSL/TLS connections for your redirect endpoint when users become authenticated, but for many apps, this will simply require a configuration update of your application server. Instructions for Apache and Nginx can be found on their respective websites, and most popular application servers will contain documentation on how to proceed.

Personal Access Token

Personal Access Tokens are a useful mechanism for accessing the API in scenarios where OAuth would be considered overkill, such as access from the command line and personal scripts or applications. A user can create many, but not unlimited, personal access tokens. When creating a token you must give it a description to help you remember what you created the token for.

Personal Access Tokens should be used similarly to OAuth access tokens when accessing the API, passing them in the Authorization header:

curl -H "Authorization: Bearer ACCESS_TOKEN" https://app.asana.com/api/1.0/users/me

You should regularly review the list of personal access tokens you have created and deauthorize those that you no longer need.

Note: Remember to keep your tokens secret; treat them just like passwords! They act on your behalf when interacting with the API. Don't hardcode them into your programs; instead, opt to use them as environment variables.

OpenID Connect

Asana also supports the OpenID Connect protocol for authenticating Asana users with your applications. This means that, in addition to the normal code and token response types for the OAuth flow, you can also use the id_token response type.

For this response type, you are not granted an access token for the API, but rather given a signed Json Web Token containing the user's ID along with some metadata. If you want to allow users to log into your services using their Asana account, the OpenID Connect protocol is an ideal way to authenticate an Asana user. To obtain an ID token, you must request the openid scope during the authentication flow.

It is also possible to obtain an ID token alongside the normal access token in the implicit flow by using the (space-delimited) token id_token response type, or alongside an authorization code in the authorization code grant flow by using the (again space-delimited) code id_token response type. If you do, the redirect parameters will include the ID token in addition to everything you would normally receive.

To access additional information about the user in a standardized format, we also expose a user info endpoint that can provide the user's name, email address, and profile photo. This data is available by making a GET request to https://app.asana.com/api/1.0/openid-connect/userinfo with an OAuth access token that has the openid scope. Depending on the scopes tied to that token, you will receive different pieces of data. Refer to our list of OAuth scopes to determine which additional scopes you need to get the data you want.

Metadata about our OpenID Connect implementation is also made available through OpenID Connect's discovery protocol. Making an unauthenticated GET request to https://app.asana.com/api/1.0/.well-known/openid-configuration will provide all the details of our implementation necessary for you to use OpenID Connect with Asana's API.

Errors

Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure (below), with a response body in JSON format containing additional information.

In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error.

Code Meaning Description
200 Success If data was requested, it will be available in the data field at the top level of the response body.
201 Created
(for object creation)
Its information is available in the data field at the top level of the response body. The API URL where the object can be retrieved is also returned in the Location header of the response.
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again.
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request.
402 Payment Required The request was valid, but the queried object or object mutation specified in the request is only available to premium organizations and workspaces.
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to.
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist.
429 Too Many Requests You have exceeded one of the enforced rate limits in the API. See the documentation on rate limiting for more information.
500 Internal Server Error There was a problem on Asana's end.

In the event of an error, the response body will contain an errors field at the top level. This contains an array of at least one error object, described below:

Example Description
Message: project: Missing input Message providing more detail about the error that occurred, if available.
Phrase: 6 sad squid snuggle softly 500 errors only. A unique error phrase which can be used when contacting developer support to help identify the exact occurrence of the problem in Asana's logs.

Some examples.

Missing authorization header

# Request curl https://app.asana.com/api/1.0/users/me

# Response HTTP/1.1 401 { "errors": [ { "message": "Not Authorized" } ] }

Bad request parameters

# Request curl -H "Authorization: Bearer " https://app.asana.com/api/1.0/tasks

# Response HTTP/1.1 400 { "errors": [ { "message": "workspace: Missing input" } ] }

Asana had a problem

# Request curl -H "Authorization: Bearer " https://app.asana.com/api/1.0/users/me

# Response HTTP/1.1 500 { "errors": [ { "message": "Server Error", "phrase": "6 sad squid snuggle softly" } ] }

Rate Limits

To protect the stability of the API and keep it available to all users, Asana enforces multiple kinds of rate limiting. Requests that hit any of our rate limits will receive a 429 Too Many Requests response, which contains the standard Retry-After header indicating how many seconds the client should wait before retrying the request.

Limits are allocated per authorization token. Different tokens will have independent limits.

The client libraries respect the rate-limited responses and will wait the appropriate amount of time before automatically retrying the request, up to a configurable maximum number of retries.

Standard Rate Limits

Our standard rate limiter imposes a quota on how many requests can be made in a given window of time. Our limits are based on minute-long windows, and differ depending on whether the domain is premium or not. We may change these quotas or add new quotas (such as maximum requests per hour) in the future.

Domain type Maximum requests per minute
Free 150
Premium 1500

In addition, calls to the search API are limited to 60 requests per minute.

Although the quota is defined per minute, it is evaluated more frequently than once per minute, so you may not need to wait for a full minute before retrying your request. For requests rejected by this limiter, the Retry-After header has the result of this calculation.

Requests rejected by this limiter still count against the quotas so that ignoring the Retry-After header will result in fewer and fewer requests being accepted during the subsequent tine windows.

Concurrent Request Limits

In addition to limiting the total number of requests in a given time window, we also limit the number of requests being handled at any given instant. We may change these limits or add new limits in the future.

Request type Maximum concurrent requests
Reads (HTTP GET method) 50
Writes (HTTP POST, PUT, PATCH, and DELETE methods combined) 15

For example, if you have 50 read requests in-flight and attempt to make another read request, the API will return a 429 Too Many Requests error. The read and write limits are independent of each other, so the number of read requests you make at one time will have no impact on the number of write requests you can make.

Responses for requests rejected by this concurrent request limiter will contain a Retry-After header specifying a duration long enough such that the other in-flight requests are guaranteed to have either completed or timed out.

Cost Limits

Objects in Asana are connected to each other in a graph. Some examples of links in this graph are:

Depending on the kind of requests you make to our API, our servers have to traverse different parts of the graph. The sizes of these parts directly influence how expensive it is for our servers to build the API responses. For example, fetching just the name and ID of a task requires very few resources and no traversal of the graph, but fetching all tasks in a project and all their attributes (assignee, followers, custom fields, likes) can require following several thousand links in the graph.

Because there can be a wide range in the cost of any given API request in terms of the computational resources and database load, the standard rate limits are not always enough to maintain stability of the API. In the past, when we’ve received bursts of expensive requests, our typical course of action has been to block the offending authorization token and reject all future requests, resulting in confusion for both the user and the app developer. Instead, to protect against the extreme cases where API requests require inordinate traversal of the graph, we impose an additional limit based on the computational cost.

The cost we associate with a request isn't equivalent to the number of links in the subset of the graph involved, but it is roughly proportional. The cost of a request is calculated after the response has been fully built and we know how much data we needed to fetch from our databases to build it. This cost is then deducted from a quota, and the response is returned. Because the cost of a request is not known until we’ve built the response, we allow this deduction to result in a net negative quota. The request that causes the quota to become negative will receive the expected response and not be rejected.

When a request is received, if the remaining quota is not positive, the new request is rejected with a 429 Too Many Requests. As with the standard rate limits, this quota is defined per-minute but is updated on a more frequent interval. The Retry-After header will specify how long you must wait for the quota to become positive again.

The vast majority of developers will be unaffected by the cost limit, and the quota is set sufficiently high that it only affects users making requests that would compromise the stability of the API. Historically, about two users per month would make requests that require intervention, which accounts for 0.0002% of all API users. Rather than unconditionally blocking their token from the API, this cost limiter will permit them to continue operation at a slower but safe and stable rate.

Rich Text

Note: In preparation for our upcoming migration to string IDs (referred to as gids in the API) this new feature uses only gids and not ids. Read more about it in our community post.

The web product offers a number of rich formatting features when writing task notes, comments, project descriptions, and project status updates. These features include bold, italic, underlined, and monospaced text, as well as bulleted and numbered lists. Additionally, users can "@-mention" other users, tasks, projects, and many other objects within Asana to create links.

The rich text field name for an object is equivalent to it's plain text field name prefixed with html_. The following object types in Asana support rich text:

Object Plain text field Rich text field
Tasks notes html_notes
Projects notes html_notes
Stories text html_text
Project status updates text html_text
Teams description html_description

Reading rich text

Rich text in the API is formatted as an HTML fragment, which is wrapped in a root <body> tag. Rich text is guaranteed to be valid XML; there will always be a root element, all tags will be closed, balanced, and case-sensitive, and all attribute values will be quoted. The following is a list of all the tags that are currently returned by the API:

Tag Meaning in Asana
<body> None
<strong> Bold text
<em> Italic text
<u> Underlined text
<s> Strikethrough text
<code> Monospaced text
<ol> Ordered list
<ul> Unordered list
<li> List item
<a> Link

Note: This list can expand as new features are introduced to the Asana web product. Treat rich text as you would treat arbitrary HTML, and ensure that your code doesn't break when it encounters a tag not on this list.

While links are easy to understand when users view the rendered in the Asana web product, an <a> tag and its href alone are insufficient to programmatically understand what the target of the link is. This is confused further by the fact that the formats of these links are frequently ambiguous. For example, an @-mention to a user generates a link to their "My Tasks", which looks identical to a link to a normal project.

Because of this, the API will return additional attributes in <a> tags to convey meaningful information about the target. The following is a complete list of attributes we may return inside an <a> tag, in addition to the usual href:

Attribute Meaning
data-asana-accessible Boolean, representing whether or not the linked object is accessible to the current user. If the resource is inaccessible, no other data-asana-* attributes will be included in the tag.
data-asana-type The type of the referenced object. One of user, task, project, tag, conversation, status_update, team, or search.
data-asana-gid The GID of the referenced object. If the referenced object is a user, this is the user's GID.
data-asana-project If the type of the referenced object is a task, and the link references that task in a particular project, this is the GID of that project.
data-asana-tag If the type of the referenced object is a task, and the link references that task in a particular tag, this is the GID of that tag.

Here are some examples of how this behavior manifests:

Here's an example of what a complete rich comment might look like in the API:

<body>All these new tasks are <em>really</em> getting disorganized, so <a href="https://app.asana.com/0/4168466/list" data-asana-accessible="true" data-asana-type="user" data-asana-gid="4168112">Tim Bizzaro</a> just made the new <a href="https://app.asana.com/0/5732985/list" data-asana-accessible="true" data-asana-type="project" data-asana-gid="5732985">Work Requests</a> project to help keep them organized. <strong>Everyone</strong> should start using the <a href="https://app.asana.com/0/5732985/6489418" data-asana-accessible="true" data-asana-type="task" data-asana-gid="6489418" data-asana-project="5732985">Request template</a> when adding new tasks there.</body>

Writing rich text

When writing rich text to the API, you must provide similarly structured, valid XML. The text must be wrapped in a <body> tag, all tags must be closed, balanced, and match the case of supported tags, and attributes must be quoted. Invalid XML, as well as unsupported tags, will be rejected with a 400 Bad Request error. Only <a> tags support attributes, and any attributes on other tags will be similarly rejected.

For <a> tags specifically, to make it easier to create @-mentions through the API, we only require that you provide the GID of the object you wish to reference. If you have access to that object, the API will automatically generate the appropriate href and other attributes for you. For example, to create a link to a task with GID "123", you can send the tag <a data-asana-gid="123"/> which will then be expanded to <a href="https://app.asana.com/0/0/123/f" data-asana-accessible="true" data-asana-type="task" data-asana-gid="123">Task Name</a>. You can also generate a link to a task in a specific project or tag by including a data-asana-project or data-asana-tag attribute in the <a> tag. All other attributes, as well as the contents of the tag, are ignored.

If you do not have access to the referenced object when you try to create a link, the API will not generate an href for you, but will instead look for an href you provide. This allows you to write back <a> tags unmodified even if you do not have access to the resource. If you do not have access to the referenced object and no href is provided, your request will be rejected with a 400 Bad Request error. Similarly, if you provide neither a GID nor a valid href, the request will be rejected with the same error.

Here's an example of what you'd send to the API when creating a comment to generate the rich text shown at the end of the previous section:

<body>All these new tasks are <em>really</em> getting disorganized, so <a data-asana-gid="4168112"/> just made the new <a data-asana-gid="5732985"/> project to help keep them organized. <strong>Everyone</strong> should start using the <a data-asana-gid="6489418" data-asana-project="5732985"/> when adding new tasks there.</body>

Parsing examples

Here are some examples in various languages of how, given some rich text, you can extract the GIDs of all the users referenced in that text using an XPath query:

# Python
from lxml import etree

html_text = "<body>...</body>"
root = etree.HTML(html_text)
user_ids = root.xpath('//a[@data-asana-type="user"]/@data-asana-gid')
for user_id in user_ids:
    print(user_id)
// Java
import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import java.util.List;

XML root = new XMLDocument("<body>...</body>");
List<String> userIds = root.xpath("//a[@data-asana-type=\"user\"]/@data-asana-gid");
for (String userId : userIds) {
    System.out.println(userId);
}
// JavaScript
var htmlText = '<body>...</body>'
var parser = new DOMParser()
var doc = parser.parseFromString(htmlText, "text/html")
var iterator = doc.evaluate(
    '//a[@data-asana-type="user"]/@data-asana-gid', doc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE)
var node = iterator.iterateNext()
while (node) {
    console.log(node.nodeValue);
    node = iterator.iterateNext();
}

Pagination

Paginating requests for object sets that may be large is highly recommended. For requests that will return large result sets the API may truncate the result or timeout attempting to gather the data. Pagination ensures a more reliable experience by limiting requests to a smaller number of objects at a time, ultimately getting you the results faster; should there be more results, the API will return an offset that will allow you to access the next page.

Strongly prefer paginated requests {#prefer-pagination}

For all new features in the Asana API, we're making pagination required by specifying a value for the limit parameter. Though they may return more results, our current unpaginated requests are still ultimately subject to a timeout limit, which means requests that work successfully one day may fail later due to factors such as server load and network latency.

Pagination limits provide a mechanism to specify a page size that we should always be able to serve regardless of these factors. To prevent current integrations from breaking, pagination is not enabled by default on "grandfathered" endpoints; instead, you can request paginated results by providing the optional limit parameter in your query. We will be working to deprecate requests to these endpoints in the future.

Note that all of Asana's official client libraries support pagination by default.

When making a paginated request, the API will return a number of results as specified by the limit parameter. If more results exist, then the response will contain a next_page attribute, which will include an offset, a relative path attribute, and a full uri attribute. If there are no more pages available, next_page will be null and no offset will be provided. Do note that an offset token will expire after some time, as data may have changed.

When making paginated requests you are able to page through all objects for a particular query up to 100 objects at a time. Alternatively your query will be truncated at about 1000 objects. In addition, when issuing non-paginated requests to organizations with a large number of objects queries may time out before returning. For these reasons, we recommend that you paginate all requests to the API.

Parameter Description
Limit 20 The number of objects to return per page. The value must be between 1 and 100.
Offset eyJ0eXAiOJiKV1iQLCJhbGciOiJIUzI1NiJ9 An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results.

Note: You can only pass in an offset that was returned to you via a previously paginated request.

This method returns paginated results for tasks from a project.

# Request curl -H "Authorization: Bearer " "https://app.asana.com/api/1.0/tasks?project=1337&limit=5&offset=eyJ0eXAiOJiKV1iQLCJhbGciOiJIUzI1NiJ9"

# Response { "data": [ { "id": 1000, "name": "Task 1", ... }, ... ], "next_page": { "offset": "yJ0eXAiOiJKV1QiLCJhbGciOiJIRzI1NiJ9", "path": "/tasks?project=1337&limit=5&offset=yJ0eXAiOiJKV1QiLCJhbGciOiJIRzI1NiJ9", "uri": "https://app.asana.com/api/1.0/tasks?project=1337&limit=5&offset=yJ0eXAiOiJKV1QiLCJhbGciOiJIRzI1NiJ9" } }

Input/Output Options

In addition to providing fields and their values in a request, you may also specify options to control how your request is interpreted and how the response is generated. For GET requests, options are specified as URL parameters prefixed with opt_. For POST or PUT requests, options are specified in the body. If the body uses the application/x-www-form-urlencoded content type, then options are prefixed with opt_ just like for GET requests. If the body uses the application/json content type, then options are specified inside the top-level options object (a sibling of the data object).

These options can be used in combination in a single request, though some of them may conflict in their impact on the response.

Option Description Notes
pretty ?opt_pretty options: { pretty: true } Provides the response in "pretty" output. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.
fields ?opt_fields=followers,assignee options: { fields: ["followers", "assignee"] } Some requests return compact representations of objects, to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.
expand ?opt_expand=followers options: { expand: ["followers"] } Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

Default output

# Request curl -H "Authorization: Bearer " https://app.asana.com/api/1.0/users/me

# Response HTTP/1.1 200 {"data":{"email":"sanchez@...","id":999,"name":"Greg Sanchez"}}

Pretty output (how all API requests in this doc are presented)

# Request curl -H "Authorization: Bearer " "https://app.asana.com/api/1.0/users/me?opt_pretty"

# Response HTTP/1.1 200 { "data": { "email": "sanchez@...", "id": 999, "name": "Greg Sanchez" } }

Get only name and description of task

# Request curl -H "Authorization: Bearer " "https://app.asana.com/api/1.0/tasks/1224?opt_fields=name,notes"

# Response HTTP/1.1 200 { "data": { "name": "Make a list", "notes": "Check it twice!", "id": 1224 } }

Reassign task, expanding projects in output

# Request curl --request PUT -H "Authorization: Bearer " https://app.asana.com/api/1.0/tasks/1001 \ -d "assignee=1234" \ -d "opt_expand=%2Aprojects%2A"

# Alternative request using JSON curl --request PUT -H "Authorization: Bearer " -H "Content-Type: application/json" \ https://app.asana.com/api/1.0/tasks/1001 -d \ '{ "data": { "assignee": 1234 }, "options": { "expand": "projects" } }'

# Response HTTP/1.1 200 { "data": { "id": 1001, "projects": [ { "archived": false, "created_at": "", "followers": [], "modified_at": "", "notes": "", "id": 1331, "name": "Things to buy" } ], ... } }

SELECTING FIELDS

Some output options allow you to reference fields of objects to include or expand in the response. The way to specify a field is by path. A path is made up of a sequence of terms separated by the dot (.) operator. It takes the form this.a.b… where this refers to an object returned at the top level of the response, a the name of a field on a root object, b a field on a child object referred to by a, and so on.

For example, when retrieving a task or tasks, the path this.followers.email refers to the email field of all users mentioned in the followers field of the task or tasks returned. See the annotated output below:

Data
"data": {
  "id": 1001,
  "name": "Feed the cat",
  "workspace": {
    "id": 14916,
    "name": "Shared Projects",
  },
  "followers": [{
    "id": 1234,
    "email": "tbizarro@…",
  }, {
    "id": 5678,
    "email": "gsanchez@…",
  }]
}
Path
this

this.name
this.workspace

this.workspace.name

this.followers

this.followers.email


this.followers.email


There are also some advanced operators you can use for shorter syntax in selecting fields:

( .. | .. )

The group operator can be used in place of any whole term in a path, and will match any of a group of terms.

this.(followers|assignee).email will match the email field of the assignee object or any of the followers.

Custom External Data

Custom external data allows a client application to add app-specific metadata to Tasks in the API. The custom data includes a string id that can be used to retrieve objects and a data blob that can store character strings.

The blob may store unicode-safe serialized data such as JSON or YAML. The external id is capped at 1,024 characters, while data blobs are capped at 32,768 characters. Each object supporting external data can have one id and one data blob stored with it. You can also use either or both of those fields.

The external id field is a good choice to create a reference between a resource in Asana and another database, such as cross-referencing an Asana task with a customer record in a CRM, or a bug in a dedicated bug tracker. Since it is just a unicode string, this field can store numeric IDs as well as URIs, however, when using URIs extra care must be taken when forming queries that the parameter is escaped correctly. By assigning an external id you can use the notation external:custom_id to reference your object anywhere that you may use the original object id.

Note: that you will need to authenticate with Oauth, as the id and data are app-specific, and these fields are not visible in the UI. This also means that external data set by one Oauth app will be invisible to all other Oauth apps. However, the data is visible to all users of the same app that can view the resource to which the data is attached, so this should not be used for private user data.

Parameter Description
id contractor_name The external id. Max size is 1024 characters. Can be a URI.
data { "time_estimate": 3600, "time_spent": 1482 } The external data blob. Max size is 32,786 characters.

Deprecations

Communicating about breaking changes

Whenever possible, the Asana API aims to preserve backwards compatibility for its users. Apps you write on top of the API now should, in ideal situations, continue to work indefinitely. However, there are a few rare cases where breaking changes are required. For example:

If a breaking change is required, the API team will provide a number of resources to help our developers get through the change:

Response header notifications

While the previously mentioned communication channels are the best place to learn about upcoming changes, the API itself will also alert you of upcoming changes. Shortly after we post communication, the API will begin sending Asana-Change headers in the responses. These headers will have two or three pieces of information:

This header may be present multiple times in the response if there are multiple ongoing changes. Here's an example of one of these headers:

Asana-Change: name=security_headers;info=https://asa.na/api-sh;affected=true
Asana-Change: name=other_change;info=https://asa.na/api-oc

Note: If your request is not affected, we will not claim affected=false. This is in case, during the deprecation, we detect that the change has a larger scope than initially thought. A request going from "you may be affected" to "you definitely are affected" is an acceptable update, but a request going from "you definitely are not affected" to "you definitely are affected" is not an acceptable update.

Request header options

During the deprecation period, you can test out how the API will behave by sending additional headers in your requests. Sending an Asana-Enable header including comma-separated names of features will turn those features on for that request. Sending an Asana-Disable header will do the opposite and turn those features off for that request.

If no header is specified, the default behavior will be determined by how far into the deprecation period we are:

The start, activation, and end dates will clearly be documented in our communications. These days may be pushed into the future if we discover that developers need more time to migrate their apps, but they are guaranteed to never occur sooner than documented.

These dates are arranged such that, if a developer happens to miss our communication and their app breaks when the default behavior changes on the activation date, they can begin sending the Asana-Disable header to restore the old behavior and use the remaining half of the deprecation period to make their app compatible.

Here's an example of how these headers would look:

Asana-Enable: security_headers,another_change
Asana-Disable: a_third_change

Aside from reserving the right to push the date of changes to a future date, the precise time during the activation date isn't specified. However, since the default will only affect your integration if you do not pass either the Asana-Enable or Asana-Disable headers for a particular deprecation you can ensure predictable behavior of our API for your app during the entire period, including throughout the activation date.

The way we recommend you implement these changes in your integration is this:

At this point, your integration has been migrated to the new behavior. At any point after the end date the Asana-Enable header will be ignored by the Asana API and you can feel free to remove it. (We strongly recommend keeping it all the way through the end date in case of unforseen circumstances that cause us to temporarily reset the default behavior from the new implementation to the deprecated behavior.)

Client library support

The latest version of our official client libraries for Python, Java, PHP, and Javascript all support sending custom headers and are able to use our deprecations framework. Consult the individual libraries for how to send headers with each request.

Active deprecations

Here is a table of recent, ongoing, and upcoming deprecations, including their header names, links to resources, and relevant dates where available. If dates are available, the next date to occur for that change is bolded.

Deprecation Header name Start date Activation date End date
Security headers security_headers 2018-08-03 2018-09-28 2018-11-15
New rich text new_rich_text 2018-08-07 2018-10-15 2018-12-17
New task subtypes new_task_subtypes 2018-10-01 See [1] 1 mo. after activation
New sections new_sections 2019-01-28 See [2] See [2]
String IDs string_ids 2019-02-12 2019-08-13 2020-02-11

[1] The activation date for this change will be one month after the public launch of the new task subtype. The end date for this change will be two months after the public launch.

[2] This migration is happening simultaneously with the rollout of a change to the Asana web app, and so the timeline for it is subject to change with ongoing development of the web app. Refer to the deprecation details for the most current information.

Asana v1.0

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

This is the interface for interacting with the Asana Platform. Our API reference is generated from our OpenAPI spec.

Base URLs:

Terms of service Web: Asana Support License: Apache 2.0

Authentication

Scope Scope Description

- Flow: implicit - Authorization URL = https://app.asana.com/-/oauth_authorize

Scope Scope Description

Attachments

An attachment object represents any file attached to a task in Asana, whether it’s an uploaded file or one associated via a third-party service such as Dropbox or Google Drive.

Get an attachment

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/attachments/12357 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/attachments/12357");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/attachments/12357",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/attachments/12357", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/attachments/12357")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/attachments/12357")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/attachments/12357");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /attachments/{attachment_gid}

Get the full record for a single attachment.

Parameters

Name In Type Required Description
attachment_gid path integer true Globally unique identifier for the attachment.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "name": "Screenshot.png",
    "created_at": "2012-02-22T02:06:58.147Z",
    "download_url": "https://www.dropbox.com/s/123/Screenshot.png?dl=1",
    "host": "dropbox",
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "view_url": "https://www.dropbox.com/s/123/Screenshot.png"
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the record for a single attachment. AttachmentObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get attachments for a task

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/124816/attachments \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/124816/attachments");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/124816/attachments",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/124816/attachments", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/124816/attachments")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/124816/attachments")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/124816/attachments");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/attachments

Returns the compact records for all attachments on the task.

Parameters

Name In Type Required Description
task_gid path integer true Globally unique identifier for the task.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "name": "Screenshot.png"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the compact records for all attachments on the task. AttachmentArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Upload an attachment

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/124816/attachments \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: multipart/form-data; boundary=---011000010111000001101001' \
  --form file=string
var data = new FormData();
data.append("file", "string");

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/124816/attachments");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/124816/attachments",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\nstring",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: multipart/form-data; boundary=---011000010111000001101001"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\nstring"

headers = {
    'content-type': "multipart/form-data; boundary=---011000010111000001101001",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/124816/attachments", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/124816/attachments")
  .header("content-type", "multipart/form-data; boundary=---011000010111000001101001")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\nstring")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/124816/attachments")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'multipart/form-data; boundary=---011000010111000001101001'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\nstring"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/124816/attachments");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001");
request.AddParameter("multipart/form-data; boundary=---011000010111000001101001", "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"\r\n\r\nstring", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/attachments

Upload an attachment.

This method uploads an attachment to a task and returns the compact record for the created attachment object. It is not possible to attach files from third party services such as Dropbox, Box & Google Drive via the API. You must download the file content first and then upload it as any other attachment.

The 100MB size limit on attachments in Asana is enforced on this endpoint.

This endpoint expects a multipart/form-data encoded request containing the full contents of the file to be uploaded.

Below is an example of what a well formed multipart/form-data encoded request might look like.

Authorization: Basic <BASE64_ENCODED_API_KEY>
Content-Type: multipart/form-data; boundary=<UNIQUE_BOUNDARY>
User-Agent: Java/1.7.0_76
Host: localhost
Accept: */*
Connection: keep-alive
Content-Length: 141

--<UNIQUE_BOUNDARY>
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

<RAW_FILE_DATA>

--<UNIQUE_BOUNDARY>--

Requests made should follow the HTTP/1.1 specification that line terminators are of the form CRLF or \r\n outlined here in order for the server to reliably and properly handle the request.

Body parameter

file: string

Parameters

Name In Type Required Description
body body object true The file you want to upload.
task_gid path integer true Globally unique identifier for the task.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

body: The file you want to upload.

Note when using curl:

Be sure to add an ‘@’ before the file path, and use the —form option instead of the -d option.

When uploading PDFs with curl, force the content-type to be pdf by appending the content type to the file path: —form “file=@file.pdf;type=application/pdf”.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "name": "Screenshot.png",
    "created_at": "2012-02-22T02:06:58.147Z",
    "download_url": "https://www.dropbox.com/s/123/Screenshot.png?dl=1",
    "host": "dropbox",
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "view_url": "https://www.dropbox.com/s/123/Screenshot.png"
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully uploaded the attachment to the task. AttachmentObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Batch API

There are many cases where you want to accomplish a variety of work in the Asana API but want to minimize the number of HTTP requests you make. For example: * Modern browsers limit the number of requests that a single web page can make at once. * Mobile apps will use more battery life to keep the cellular radio on when making a series of requests. * There is an overhead cost to developing software that can make multiple requests in parallel. * Some cloud platforms handle parallelism poorly, or disallow it entirely. * To make development easier in these use cases, Asana provides a batch API that enables developers to perform multiple “actions” by making only a single HTTP request.

Making a Batch Request

To make a batch request, send a POST request to /batch. Like other POST endpoints, the body should contain a data envelope. Inside this envelope should be a single actions field, containing a list of “action” objects. Each action represents a standard request to an existing endpoint in the Asana API. The maximum number of actions allowed in a single batch request is 10. Making a batch request with no actions in it will result in a 400 Bad Request. When the batch API receives the list of actions to execute, it will dispatch those actions to the already-implemented endpoints specified by the relative_path and method for each action. This happens in parallel, so all actions in the request will be processed simultaneously. There is no guarantee of the execution order for these actions, nor is there a way to use the output of one action as the input of another action (such as creating a task and then commenting on it). The response to the batch request will contain (within the data envelope) a list of result objects, one for each action. The results are guaranteed to be in the same order as the actions in the request, e.g., the first result in the response corresponds to the first action in the request. The batch API will always attempt to return a 200 Success response with individual result objects for each individual action in the request. Only in certain cases (such as missing authorization or malformed JSON in the body) will the entire request fail with another status code. Even if every individual action in the request fails, the batch API will still return a 200 Success response, and each result object in the response will contain the errors encountered with each action.

Rate Limiting

The batch API fully respects all of our rate limiting. This means that a batch request counts against both the standard rate limiter and the concurrent request limiter as though you had made a separate HTTP request for every individual action. For example, a batch request with five actions counts as five separate requests in the standard rate limiter, and counts as five concurrent requests in the concurrent request limiter. The batch request itself incurs no cost. If any of the actions in a batch request would exceed any of the enforced limits, the entire request will fail with a 429 Too Many Requests error. This is to prevent the unpredictability of which actions might succeed if not all of them could succeed.

Restrictions

Not every endpoint can be accessed through the batch API. Specifically, the following actions cannot be taken and will result in a 400 Bad Request for that action: * Uploading attachments * Creating, getting, or deleting organization exports * Any SCIM operations * Nested calls to the batch API

Submit parallel requests

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/batch \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"actions":[{"relative_path":"/tasks/123","method":"get","data":{"assignee":"me","workspace":1337},"options":{"limit":3,"fields":["name","notes","completed"]}}]}}'
var data = JSON.stringify({
  "data": {
    "actions": [
      {
        "relative_path": "/tasks/123",
        "method": "get",
        "data": {
          "assignee": "me",
          "workspace": 1337
        },
        "options": {
          "limit": 3,
          "fields": [
            "name",
            "notes",
            "completed"
          ]
        }
      }
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/batch");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/batch",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"actions\":[{\"relative_path\":\"/tasks/123\",\"method\":\"get\",\"data\":{\"assignee\":\"me\",\"workspace\":1337},\"options\":{\"limit\":3,\"fields\":[\"name\",\"notes\",\"completed\"]}}]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"actions\":[{\"relative_path\":\"/tasks/123\",\"method\":\"get\",\"data\":{\"assignee\":\"me\",\"workspace\":1337},\"options\":{\"limit\":3,\"fields\":[\"name\",\"notes\",\"completed\"]}}]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/batch", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/batch")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"actions\":[{\"relative_path\":\"/tasks/123\",\"method\":\"get\",\"data\":{\"assignee\":\"me\",\"workspace\":1337},\"options\":{\"limit\":3,\"fields\":[\"name\",\"notes\",\"completed\"]}}]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/batch")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"actions\":[{\"relative_path\":\"/tasks/123\",\"method\":\"get\",\"data\":{\"assignee\":\"me\",\"workspace\":1337},\"options\":{\"limit\":3,\"fields\":[\"name\",\"notes\",\"completed\"]}}]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/batch");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"actions\":[{\"relative_path\":\"/tasks/123\",\"method\":\"get\",\"data\":{\"assignee\":\"me\",\"workspace\":1337},\"options\":{\"limit\":3,\"fields\":[\"name\",\"notes\",\"completed\"]}}]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /batch

Make multiple requests in parallel to Asana's API.

Body parameter

{
  "data": {
    "actions": [
      {
        "relative_path": "/tasks/123",
        "method": "get",
        "data": {
          "assignee": "me",
          "workspace": 1337
        },
        "options": {
          "limit": 3,
          "fields": [
            "name",
            "notes",
            "completed"
          ]
        }
      }
    ]
  }
}

Parameters

Name In Type Required Description
body body object true The requests to batch together via the Batch API.
» data body object false none
»» actions body [BatchRequest] false [A request object for use in a batch request.]
»»» relative_path body string true The path of the desired endpoint relative to the API’s base URL. Query parameters are not accepted here; put them in data instead.
»»» method body string true The HTTP method you wish to emulate for the action.
»»» data body object false For GET requests, this should be a map of query parameters you would have normally passed in the URL. Options and pagination are not accepted here; put them in options instead. For POST, PATCH, and PUT methods, this should be the content you would have normally put in the data field of the body.
»»» options body object false Pagination (limit and offset) and output options (fields or expand) for the action. “Pretty” JSON output is not an available option on individual actions; if you want pretty output, specify that option on the parent request.
»»»» limit body integer false Pagination limit for the request.
»»»» offset body integer false Pagination offset for the request.
»»»» fields body [string] false The fields to retrieve in the request.
»»»» expand body string false The expansion path for the request.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
»»» method get
»»» method post
»»» method put
»»» method delete
»»» method patch
»»» method head

Example responses

200 Response

{
  "data": [
    {
      "status_code": 200,
      "headers": {
        "location": "/tasks/1234"
      },
      "body": {
        "data": {
          "id": 1967,
          "completed": false,
          "name": "Hello, world!",
          "notes": "How are you today?"
        }
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully completed the requested batch API operations. Inline
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
» data [BatchResponse] false none [A response object returned from a batch request.]
»» status_code integer false none The HTTP status code that the invoked endpoint returned.
»» headers object false none A map of HTTP headers specific to this result. This is primarily used for returning a Location header to accompany a 201 Created result. The parent HTTP response will contain all common headers.
»» body object false none The JSON body that the invoked endpoint returned.

Custom Fields

In the Asana application, Tasks can hold user-specified Custom Fields which provide extra information; for example, a priority value or a number representing the time required to complete a Task. This lets a user define the type of information that each Task within a Project can contain in addition to the built-in fields that Asana provides. Note: Custom Fields are a premium feature. Integrations which work with Custom Fields need to handle an assortment of use cases for free and premium users in context of free and premium organizations. For a detailed examination of to what data users will have access in different circumstances, read the section below on access control. The characteristics of Custom Fields are: * There is metadata that defines the Custom Field. This metadata is shared across an entire organization or workspace. * Projects can have Custom Fields associated with them individually. This is conceptually akin to adding columns in a database or a spreadsheet: every Task (row) in the Project (table) can contain information for that field, including "blank" values, i.e. null data. * Tasks have Custom Field values assigned to them. A brief example: let's imagine that an organization has defined a Custom Field for "Priority". This field is of enum type and can have user-defined values of Low, Medium, or High. This is the field metadata, and it is visible within, and shared across, the entire organization. A Project is then created in the organization, called "Bugs", and the "Priority" Custom Field is associated with that Project. This will allow all Tasks within the "Bugs" Project to have an associated "Priority". A new Task is created within "Bugs". This Task, then, has a field named "Priority" which can take on the Custom Field value of one of [null], Low, Medium, and High. These Custom Fields are accessible via the API through a number of endpoints at the top level (e.g. /custom_fields and /custom_field_settings) and through calls on Workspaces, Projects, and Tasks resources. The API also provides a way to fetch both the metadata and data which define each particular Custom Field, so that a client application may render proper UI to display or edit the values. Custom Field aware integrations need to be aware of the basic types that Custom Fields can adopt. These types are: * text - an arbitrary, relatively short string of text * number - a number with a defined level of precision * enum - a selection from a defined list of options Text fields are currently limited to 1024 characters. On Tasks, their Custom Field value will have a text_value property to represent this field. Number fields can have an arbitrary precision associated with them; for example, a precision of 2 would round its value to the second (hundredths) place, i.e. 1.2345 would round to 1.23. On Tasks, the Custom Field value will have a number_value property to represent this field. Enum fields represent a selection from a list of options. On the metadata, they will contain all of the options in an array. Each option has 4 properties: * id - the id of this enum option. Note that this is the id of the option - the Custom Field itself has a separate id. * name - the name of the option, e.g. "Choice #1" * enabled - whether this field is enabled. Disabled fields are not available to choose from when disabled, and are visually hidden in the Asana application, but they remain in the metadata for Custom Field values which were set to the option before the option was disabled. * color - a color associated with this choice. On the Task's Custom Field value, the enum will have an enum_value property which will be the same as one of the choices from the list defined in the Custom Field metadata. The Custom Field API Reference contains information about the specifics of how to use Custom Fields in conjunction with Asana's API.

Create a custom field

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/custom_fields \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Bug Task","resource_subtype":"milestone","type":"text","enum_options":[{"name":"Low","enabled":true,"color":"blue"}],"enum_value":{"name":"Low","enabled":true,"color":"blue"},"enabled":true,"text_value":"Some Value","description":"Development team priority","precision":2,"workspace":1331}}'
var data = JSON.stringify({
  "data": {
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2,
    "workspace": 1331
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/custom_fields");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/custom_fields",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2,\"workspace\":1331}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2,\"workspace\":1331}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/custom_fields", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/custom_fields")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2,\"workspace\":1331}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/custom_fields")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2,\"workspace\":1331}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/custom_fields");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2,\"workspace\":1331}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /custom_fields

Creates a new custom field in a workspace. Every custom field is required to be created in a specific workspace, and this workspace cannot be changed once set.

A custom field’s name must be unique within a workspace and not conflict with names of existing task properties such as ‘Due Date’ or ‘Assignee’. A custom field’s type must be one of ‘text’, ‘enum’, or ‘number’.

Returns the full record of the newly created custom field.

Body parameter

{
  "data": {
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2,
    "workspace": 1331
  }
}

Parameters

Name In Type Required Description
body body object true The custom field object to create.
» data body any false none
»» anonymous body any false none
»»» anonymous body any false none
»»»» anonymous body any false none
»»»»» anonymous body AsanaObject false A generic Asana Object, containing a globally unique identifier.
»»»»»» id body integer(int64) false Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»»»»» gid body string false Globally unique ID of the object, as a string.
»»»»»» resource_type body string false The base type of this resource.
»»»»» anonymous body object false none
»»»»»» name body string false The name of the object.
»»»»» anonymous body object false none
»»»»»» resource_subtype body string false The subtype of this resource. Different subtypes retain many of the same fields and behavior, but may render differently in Asana or represent resources with different semantic meaning.
»»»»» anonymous body object false none
»»»»»» type body string false Deprecated: new integrations should prefer the resource_subtype field. The type of the custom field. Must be one of the given values.
»»»»»» enum_options body array false Conditional. Only relevant for custom fields of type enum. This array specifies the possible values which an enum custom field can adopt. To modify the enum options, refer to working with enum options.
»»»»»»» anonymous body any false none
»»»»»» enum_value body any false none
»»»»»»» anonymous body any false none
»»»»»»»» anonymous body AsanaObject false A generic Asana Object, containing a globally unique identifier.
»»»»»»»» anonymous body object false Enum options are the possible values which an enum custom field can
»»»»»»»»» name body string false The name of the enum option.
»»»»»»»»» enabled body boolean false The color of the enum option. Defaults to ‘none’.
»»»»»»»»» color body string false Whether or not the enum option is a selectable value for the custom field.
»»»»»»»» anonymous body object false Conditional. Only relevant for custom fields of type enum. This object is the chosen value of an enum custom field.
»»»»»»» enabled body boolean false Conditional. Determines if the custom field is enabled or not.
»»»»»»» text_value body string false Conditional. This string is the value of a text custom field.
»»»»»» anonymous body object false Custom Fields store the metadata that is used in order to
»»»»»»» description body string false Opt In. The description of the custom field.
»»»»»»» enum_options body [allOf] false Conditional. Only relevant for custom fields of type enum. This array specifies the possible values which an enum custom field can adopt. To modify the enum options, refer to working with enum options.
»»»»»»» precision body integer false Only relevant for custom fields of type ‘Number’. This field dictates the number of places after the decimal to round to, i.e. 0 is integer values, 1 rounds to the nearest tenth, and so on. Must be between 0 and 6, inclusive.
»»»»»» anonymous body object false none
»»»»»»» workspace body integer true The workspace to create a custom field in.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

»»»»»»»» *anonymous*: Enum options are the possible values which an enum custom field can adopt. An enum custom field must contain at least 1 enum option but no more than 50.

You can add enum options to a custom field by using the POST /custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum options can be disabled by updating the enabled field to false with the PUT /enum_options/enum_option_gid endpoint. Other attributes can be updated similarly.

On creation of an enum option, enabled is always set to true, meaning the enum option is a selectable value for the custom field. Setting enabled=false is equivalent to “trashing” the enum option in the Asana web app within the “Edit Fields” dialog. The enum option will no longer be selectable but, if the enum option value was previously set within a task, the task will retain the value.

Enum options are an ordered list and by default new enum options are inserted at the end. Ordering in relation to existing enum options can be specified on creation by using insert_before or insert_after to reference an existing enum option. Only one of insert_before and insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST /custom_fields/custom_field_gid/enum_options/insert endpoint.

»»»»»» *anonymous*: Custom Fields store the metadata that is used in order to add user-specified information to tasks in Asana. Be sure to reference the Custom Fields developer documentation for more information about how custom fields relate to various resources in Asana.

Users in Asana can lock custom fields, which will make them read-only when accessed by other users. Attempting to edit a locked custom field will return HTTP error code 403 Forbidden.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
»»»»»» type text
»»»»»» type enum
»»»»»» type number

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
}

Responses

Status Meaning Description Schema
201 Created Custom field successfully created. CustomFieldObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a custom field definition

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/custom_fields/124578 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/custom_fields/124578");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/custom_fields/124578",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/custom_fields/124578", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/custom_fields/124578")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/custom_fields/124578")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/custom_fields/124578");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /custom_fields/{custom_field_gid}

Get the complete definition of a custom field’s metadata.

Since custom fields can be defined for one of a number of types, and these types have different data and behaviors, there are fields that are relevant to a particular type. For instance, as noted above, enum_options is only relevant for the enum type and defines the set of choices that the enum could represent. The examples below show some of these type-specific custom field definitions.

Get the metadata for a custom field of type ‘text’

# Request
curl -H "Authorization: Bearer <personal_access_token>" \
https://app.asana.com/api/1.0/custom_fields/124578
# Response
HTTP/1.1 200
{
  "data": [
    {
      "id": 134679,
      "name": "Owner",
      "description": "Person responsible for task",
      "type": "text"
    }
  ]
}

Get the metadata for a custom field of type ‘number’

# Request
curl -H "Authorization: Bearer <personal_access_token>" \
https://app.asana.com/api/1.0/custom_fields/124578
# Response
HTTP/1.1 200
{
  "data": [
    {
      "id": 938271,
      "name": "Price",
      "description": "In US Dollars",
      "type": "number",
      "precision": 2
    }
  ]
}

Get the metadata for a custom field when that field is of type ‘enum’.

# Request
curl -H "Authorization: Bearer <personal_access_token>" \
https://app.asana.com/api/1.0/custom_fields/124578
# Response
HTTP/1.1 200
{
  "data": [
    {
      "id": 124578,
      "name": "Priority",
      "description": "Development team priority",
      "type": "enum",
      "enum_options": [
        {
          "id": 789,
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        {
          "id": 208,
          "name": "Medium",
          "enabled": false,
          "color": "yellow"
        },
        {
          "id": 439,
          "name": "High",
          "enabled": true,
          "color": "red"
        }
      ]
    }
  ]
}

Parameters

Name In Type Required Description
custom_field_gid path integer true Globally unique identifier for the custom field.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the complete definition of a custom field’s metadata. CustomFieldObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a custom field

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/custom_fields/124578 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Bug Task","resource_subtype":"milestone","type":"text","enum_options":[{"name":"Low","enabled":true,"color":"blue"}],"enum_value":{"name":"Low","enabled":true,"color":"blue"},"enabled":true,"text_value":"Some Value","description":"Development team priority","precision":2}}'
var data = JSON.stringify({
  "data": {
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/custom_fields/124578");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/custom_fields/124578",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/custom_fields/124578", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/custom_fields/124578")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/custom_fields/124578")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/custom_fields/124578");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\",\"description\":\"Development team priority\",\"precision\":2}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /custom_fields/{custom_field_gid}

A specific, existing custom field can be updated by making a PUT request on the URL for that custom field. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged When using this method, it is best to specify only those fields you wish to change, or else you may overwrite changes made by another user since you last retrieved the custom field. A custom field’s type cannot be updated. An enum custom field’s enum_options cannot be updated with this endpoint. Instead see “Work With Enum Options” for information on how to update enum_options. Locked custom fields can only be updated by the user who locked the field. Returns the complete updated custom field record.

Body parameter

{
  "data": {
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
}

Parameters

Name In Type Required Description
body body CustomFieldObject true The custom field object with all updated properties.
custom_field_gid path integer true Globally unique identifier for the custom field.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
}

Responses

Status Meaning Description Schema
200 OK The custom field was successfully updated. CustomFieldObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a custom field

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/custom_fields/124578 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/custom_fields/124578");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/custom_fields/124578",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/custom_fields/124578", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/custom_fields/124578")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/custom_fields/124578")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/custom_fields/124578");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /custom_fields/{custom_field_gid}

A specific, existing custom field can be deleted by making a DELETE request on the URL for that custom field. Locked custom fields can only be deleted by the user who locked the field. Returns an empty data record.

Parameters

Name In Type Required Description
custom_field_gid path integer true Globally unique identifier for the custom field.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK The custom field was successfully deleted. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create an enum option

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/custom_fields/124578/enum_options \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Low","enabled":true,"color":"blue","insert_before":12345}}'
var data = JSON.stringify({
  "data": {
    "name": "Low",
    "enabled": true,
    "color": "blue",
    "insert_before": 12345
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/custom_fields/124578/enum_options");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/custom_fields/124578/enum_options",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"insert_before\":12345}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"insert_before\":12345}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/custom_fields/124578/enum_options", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/custom_fields/124578/enum_options")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"insert_before\":12345}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/custom_fields/124578/enum_options")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"insert_before\":12345}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/custom_fields/124578/enum_options");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"insert_before\":12345}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /custom_fields/{custom_field_gid}/enum_options

Creates an enum option and adds it to this custom field’s list of enum options. A custom field can have at most 50 enum options (including disabled options). By default new enum options are inserted at the end of a custom field’s list. Locked custom fields can only have enum options added by the user who locked the field. Returns the full record of the newly created enum option.

Body parameter

{
  "data": {
    "name": "Low",
    "enabled": true,
    "color": "blue",
    "insert_before": 12345
  }
}

Parameters

Name In Type Required Description
body body object true The enum option object to create.
» data body any false none
»» anonymous body any false none
»»» anonymous body AsanaObject false A generic Asana Object, containing a globally unique identifier.
»»»» id body integer(int64) false Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»»» gid body string false Globally unique ID of the object, as a string.
»»»» resource_type body string false The base type of this resource.
»»» anonymous body object false Enum options are the possible values which an enum custom field can
»»»» name body string false The name of the enum option.
»»»» enabled body boolean false The color of the enum option. Defaults to ‘none’.
»»»» color body string false Whether or not the enum option is a selectable value for the custom field.
»»» anonymous body any false none
»»»» anonymous body object false none
»»»»» insert_before body integer false An existing enum option within this custom field before which the new enum option should be inserted. Cannot be provided together with after_enum_option.
»»»» anonymous body object false none
»»»»» insert_after body integer false An existing enum option within this custom field after which the new enum option should be inserted. Cannot be provided together with before_enum_option.
custom_field_gid path integer true Globally unique identifier for the custom field.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

»»» *anonymous*: Enum options are the possible values which an enum custom field can adopt. An enum custom field must contain at least 1 enum option but no more than 50.

You can add enum options to a custom field by using the POST /custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum options can be disabled by updating the enabled field to false with the PUT /enum_options/enum_option_gid endpoint. Other attributes can be updated similarly.

On creation of an enum option, enabled is always set to true, meaning the enum option is a selectable value for the custom field. Setting enabled=false is equivalent to “trashing” the enum option in the Asana web app within the “Edit Fields” dialog. The enum option will no longer be selectable but, if the enum option value was previously set within a task, the task will retain the value.

Enum options are an ordered list and by default new enum options are inserted at the end. Ordering in relation to existing enum options can be specified on creation by using insert_before or insert_after to reference an existing enum option. Only one of insert_before and insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST /custom_fields/custom_field_gid/enum_options/insert endpoint.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Low",
    "enabled": true,
    "color": "blue"
  }
}

Responses

Status Meaning Description Schema
201 Created Custom field enum option successfully created. Inline
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Response Schema

Status Code 201

Name Type Required Restrictions Description
» data any false none none

allOf

Name Type Required Restrictions Description
»» anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.
»»» id integer(int64) false read-only Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»» gid string false read-only Globally unique ID of the object, as a string.
»»» resource_type string false read-only The base type of this resource.

and

Name Type Required Restrictions Description
»» anonymous object false none Enum options are the possible values which an enum custom field can
adopt. An enum custom field must contain at least 1 enum option but no
more than 50.

You can add enum options to a custom field by using the POST<br>/custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum
options can be disabled by updating the enabled field to false with the
PUT /enum_options/enum_option_gid endpoint. Other attributes can be
updated similarly.

On creation of an enum option, enabled is always set to true, meaning
the enum option is a selectable value for the custom field. Setting
enabled=false is equivalent to “trashing” the enum option in the Asana
web app within the “Edit Fields” dialog. The enum option will no longer
be selectable but, if the enum option value was previously set within a
task, the task will retain the value.

Enum options are an ordered list and by default new enum options are
inserted at the end. Ordering in relation to existing enum options can be
specified on creation by using insert_before or insert_after to
reference an existing enum option. Only one of insert_before and
insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST<br>/custom_fields/custom_field_gid/enum_options/insert endpoint.
»»» name string false none The name of the enum option.
»»» enabled boolean false none The color of the enum option. Defaults to ‘none’.
»»» color string false none Whether or not the enum option is a selectable value for the custom field.

Reorder a custom field's enum

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/custom_fields/124578/enum_options/insert \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Low","enabled":true,"color":"blue","enum_option":97285,"before_enum_option":12345}}'
var data = JSON.stringify({
  "data": {
    "name": "Low",
    "enabled": true,
    "color": "blue",
    "enum_option": 97285,
    "before_enum_option": 12345
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/custom_fields/124578/enum_options/insert");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/custom_fields/124578/enum_options/insert",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"enum_option\":97285,\"before_enum_option\":12345}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"enum_option\":97285,\"before_enum_option\":12345}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/custom_fields/124578/enum_options/insert", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/custom_fields/124578/enum_options/insert")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"enum_option\":97285,\"before_enum_option\":12345}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/custom_fields/124578/enum_options/insert")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"enum_option\":97285,\"before_enum_option\":12345}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/custom_fields/124578/enum_options/insert");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\",\"enum_option\":97285,\"before_enum_option\":12345}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /custom_fields/{custom_field_gid}/enum_options/insert

Moves a particular enum option to be either before or after another specified enum option in the custom field. Locked custom fields can only be reordered by the user who locked the field.

Body parameter

{
  "data": {
    "name": "Low",
    "enabled": true,
    "color": "blue",
    "enum_option": 97285,
    "before_enum_option": 12345
  }
}

Parameters

Name In Type Required Description
body body object true The enum option object to create.
» data body any false none
»» anonymous body any false none
»»» anonymous body AsanaObject false A generic Asana Object, containing a globally unique identifier.
»»»» id body integer(int64) false Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»»» gid body string false Globally unique ID of the object, as a string.
»»»» resource_type body string false The base type of this resource.
»»» anonymous body object false Enum options are the possible values which an enum custom field can
»»»» name body string false The name of the enum option.
»»»» enabled body boolean false The color of the enum option. Defaults to ‘none’.
»»»» color body string false Whether or not the enum option is a selectable value for the custom field.
»»» anonymous body object false none
»»»» enum_option body integer false The ID of the enum option to relocate.
»»» anonymous body any false none
»»»» anonymous body object false none
»»»»» before_enum_option body integer false An existing enum option within this custom field before which the new enum option should be inserted. Cannot be provided together with after_enum_option.
»»»» anonymous body object false none
»»»»» after_enum_option body integer false An existing enum option within this custom field after which the new enum option should be inserted. Cannot be provided together with before_enum_option.
custom_field_gid path integer true Globally unique identifier for the custom field.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

»»» *anonymous*: Enum options are the possible values which an enum custom field can adopt. An enum custom field must contain at least 1 enum option but no more than 50.

You can add enum options to a custom field by using the POST /custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum options can be disabled by updating the enabled field to false with the PUT /enum_options/enum_option_gid endpoint. Other attributes can be updated similarly.

On creation of an enum option, enabled is always set to true, meaning the enum option is a selectable value for the custom field. Setting enabled=false is equivalent to “trashing” the enum option in the Asana web app within the “Edit Fields” dialog. The enum option will no longer be selectable but, if the enum option value was previously set within a task, the task will retain the value.

Enum options are an ordered list and by default new enum options are inserted at the end. Ordering in relation to existing enum options can be specified on creation by using insert_before or insert_after to reference an existing enum option. Only one of insert_before and insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST /custom_fields/custom_field_gid/enum_options/insert endpoint.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Low",
    "enabled": true,
    "color": "blue"
  }
}

Responses

Status Meaning Description Schema
200 OK Custom field enum option successfully reordered. Inline
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
» data any false none none

allOf

Name Type Required Restrictions Description
»» anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.
»»» id integer(int64) false read-only Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»» gid string false read-only Globally unique ID of the object, as a string.
»»» resource_type string false read-only The base type of this resource.

and

Name Type Required Restrictions Description
»» anonymous object false none Enum options are the possible values which an enum custom field can
adopt. An enum custom field must contain at least 1 enum option but no
more than 50.

You can add enum options to a custom field by using the POST<br>/custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum
options can be disabled by updating the enabled field to false with the
PUT /enum_options/enum_option_gid endpoint. Other attributes can be
updated similarly.

On creation of an enum option, enabled is always set to true, meaning
the enum option is a selectable value for the custom field. Setting
enabled=false is equivalent to “trashing” the enum option in the Asana
web app within the “Edit Fields” dialog. The enum option will no longer
be selectable but, if the enum option value was previously set within a
task, the task will retain the value.

Enum options are an ordered list and by default new enum options are
inserted at the end. Ordering in relation to existing enum options can be
specified on creation by using insert_before or insert_after to
reference an existing enum option. Only one of insert_before and
insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST<br>/custom_fields/custom_field_gid/enum_options/insert endpoint.
»»» name string false none The name of the enum option.
»»» enabled boolean false none The color of the enum option. Defaults to ‘none’.
»»» color string false none Whether or not the enum option is a selectable value for the custom field.

Update an enum option.

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/enum_options/124578 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Low","enabled":true,"color":"blue"}}'
var data = JSON.stringify({
  "data": {
    "name": "Low",
    "enabled": true,
    "color": "blue"
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/enum_options/124578");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/enum_options/124578",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/enum_options/124578", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/enum_options/124578")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/enum_options/124578")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/enum_options/124578");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /enum_options/{enum_option_gid}

Updates an existing enum option. Enum custom fields require at least one enabled enum option. Locked custom fields can only be updated by the user who locked the field. Returns the full record of the updated enum option.

Body parameter

{
  "data": {
    "name": "Low",
    "enabled": true,
    "color": "blue"
  }
}

Parameters

Name In Type Required Description
body body object true The enum option object to update
» data body any false none
»» anonymous body AsanaObject false A generic Asana Object, containing a globally unique identifier.
»»» id body integer(int64) false Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»» gid body string false Globally unique ID of the object, as a string.
»»» resource_type body string false The base type of this resource.
»» anonymous body object false Enum options are the possible values which an enum custom field can
»»» name body string false The name of the enum option.
»»» enabled body boolean false The color of the enum option. Defaults to ‘none’.
»»» color body string false Whether or not the enum option is a selectable value for the custom field.
enum_option_gid path integer true Globally unique identifier for the enum option.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

»» *anonymous*: Enum options are the possible values which an enum custom field can adopt. An enum custom field must contain at least 1 enum option but no more than 50.

You can add enum options to a custom field by using the POST /custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum options can be disabled by updating the enabled field to false with the PUT /enum_options/enum_option_gid endpoint. Other attributes can be updated similarly.

On creation of an enum option, enabled is always set to true, meaning the enum option is a selectable value for the custom field. Setting enabled=false is equivalent to “trashing” the enum option in the Asana web app within the “Edit Fields” dialog. The enum option will no longer be selectable but, if the enum option value was previously set within a task, the task will retain the value.

Enum options are an ordered list and by default new enum options are inserted at the end. Ordering in relation to existing enum options can be specified on creation by using insert_before or insert_after to reference an existing enum option. Only one of insert_before and insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST /custom_fields/custom_field_gid/enum_options/insert endpoint.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Low",
    "enabled": true,
    "color": "blue"
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully updated the specified custom field enum. Inline
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Response Schema

Status Code 200

Name Type Required Restrictions Description
» data any false none none

allOf

Name Type Required Restrictions Description
»» anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.
»»» id integer(int64) false read-only Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
»»» gid string false read-only Globally unique ID of the object, as a string.
»»» resource_type string false read-only The base type of this resource.

and

Name Type Required Restrictions Description
»» anonymous object false none Enum options are the possible values which an enum custom field can
adopt. An enum custom field must contain at least 1 enum option but no
more than 50.

You can add enum options to a custom field by using the POST<br>/custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum
options can be disabled by updating the enabled field to false with the
PUT /enum_options/enum_option_gid endpoint. Other attributes can be
updated similarly.

On creation of an enum option, enabled is always set to true, meaning
the enum option is a selectable value for the custom field. Setting
enabled=false is equivalent to “trashing” the enum option in the Asana
web app within the “Edit Fields” dialog. The enum option will no longer
be selectable but, if the enum option value was previously set within a
task, the task will retain the value.

Enum options are an ordered list and by default new enum options are
inserted at the end. Ordering in relation to existing enum options can be
specified on creation by using insert_before or insert_after to
reference an existing enum option. Only one of insert_before and
insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST<br>/custom_fields/custom_field_gid/enum_options/insert endpoint.
»»» name string false none The name of the enum option.
»»» enabled boolean false none The color of the enum option. Defaults to ‘none’.
»»» color string false none Whether or not the enum option is a selectable value for the custom field.

Get a workspace's custom fields

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces/1331/custom_fields \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/1331/custom_fields");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/1331/custom_fields",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/1331/custom_fields", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/1331/custom_fields")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/1331/custom_fields")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/1331/custom_fields");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}/custom_fields

Returns a list of the compact representation of all of the custom fields in a workspace.

Parameters

Name In Type Required Description
workspace_gid path integer true The workspace or organization to find custom field definitions in.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved all custom fields for the given workspace. CustomFieldArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Custom Field Settings

Custom Fields Settings objects represent the many-to-many join of the Custom Field and Project as well as stores information that is relevant to that particular pairing.

Get a project's custom fields

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects/13579/custom_field_settings \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects/13579/custom_field_settings");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/13579/custom_field_settings",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects/13579/custom_field_settings", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects/13579/custom_field_settings")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/13579/custom_field_settings")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/13579/custom_field_settings");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects/{project_gid}/custom_field_settings

Returns a list of all of the custom fields settings on a project, in compact form. Note that, as in all queries to collections which return compact representation, opt_fields and opt_expand can be used to include more data than is returned in the compact representation. See the getting started guide on input/output options for more information.

Parameters

Name In Type Required Description
project_gid path string true The ID of the project for which to list custom field settings.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "is_important": false,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved custom field settings objects for a project. CustomFieldSettingsArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a portfolio's custom fields

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/portfolios/13579/custom_field_settings \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/portfolios/13579/custom_field_settings");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/13579/custom_field_settings",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/portfolios/13579/custom_field_settings", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/portfolios/13579/custom_field_settings")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/13579/custom_field_settings")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/13579/custom_field_settings");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /portfolios/{portfolio_gid}/custom_field_settings

Returns a list of all of the custom fields settings on a portfolio, in compact form.

Parameters

Name In Type Required Description
portfolio_gid path string true The ID of the portfolio for which to list custom field settings.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "is_important": false,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved custom field settings objects for a portfolio. CustomFieldSettingsArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Events

An event is an object representing a change to a resource that was observed by an event subscription.

Get events on a resource

Code samples

curl --request GET \
  --url 'https://app.asana.com/api/1.0/events?resource=12345' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/events?resource=12345");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/events?resource=12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/events?resource=12345", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/events?resource=12345")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/events?resource=12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/events?resource=12345");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /events

Returns the full record for all events that have occurred since the sync token was created.

A GET request to the endpoint /[path_to_resource]/events can be made in lieu of including the resource ID in the data for the request.

Parameters

Name In Type Required Description
resource query integer true A resource ID to subscribe to. The resource can be a task or project.
sync query string false A sync token received from the last request, or none on first sync. Events will be returned from the point in time that the sync token was generated.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

sync: A sync token received from the last request, or none on first sync. Events will be returned from the point in time that the sync token was generated. Note: On your first request, omit the sync token. The response will be the same as for an expired sync token, and will include a new valid sync token.If the sync token is too old (which may happen from time to time) the API will return a 412 Precondition Failed error, and include a fresh sync token in the response.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "user": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "resource": {
        "id": 12345,
        "name": "Bug Task"
      },
      "type": "task",
      "action": "changed",
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "created_at": "2012-02-22T02:06:58.147Z"
    }
  ],
  "sync": "de4774f6915eae04714ca93bb2f5ee81"
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved events. EventArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Jobs

Jobs represent processes that handle asynchronous work. Jobs are created when an endpoint requests an action that will be handled asynchronously. Such as project or task duplication. Only the creator of the duplication process can access the duplication status of the new object.

Get a job by id

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/jobs/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/jobs/12345");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/jobs/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/jobs/12345", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/jobs/12345")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/jobs/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/jobs/12345");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /jobs/{job_gid}

Returns the full record for a job.

Parameters

Name In Type Required Description
job_gid path string true Globally unique identifier for the job.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "status": "in_progress",
    "new_project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "new_task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved Job. JobObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Organization Exports

An organization_export object represents a request to export the complete data of an Organization in JSON format.

Create an organization export request

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/organization_exports \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"organization":1331}'
var data = JSON.stringify({
  "organization": 1331
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/organization_exports");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/organization_exports",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"organization\":1331}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"organization\":1331}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/organization_exports", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/organization_exports")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"organization\":1331}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/organization_exports")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"organization\":1331}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/organization_exports");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"organization\":1331}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /organization_exports

This method creates a request to export an Organization. Asana will complete the export at some point after you create the request.

Body parameter

{
  "organization": 1331
}

Parameters

Name In Type Required Description
body body object true The organization to export.
» organization body integer false Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "download_url": "https://asana-export.s3.amazonaws.com/export-4632784536274-20170127-43246.json.gz?AWSAccessKeyId=xxxxxxxx",
    "state": "started",
    "organization": {
      "id": 14916,
      "gid": "14916",
      "name": "My Workspace"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created organization export request. OrganizationExportObjectResponse
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get details on an org export request

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/organization_exports/133549 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/organization_exports/133549");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/organization_exports/133549",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/organization_exports/133549", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/organization_exports/133549")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/organization_exports/133549")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/organization_exports/133549");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /organization_exports/{organization_export_gid}

Returns details of a previously-requested Organization export.

Parameters

Name In Type Required Description
organization_export_gid path integer true Globally unique identifier for the organization export.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "download_url": "https://asana-export.s3.amazonaws.com/export-4632784536274-20170127-43246.json.gz?AWSAccessKeyId=xxxxxxxx",
    "state": "started",
    "organization": {
      "id": 14916,
      "gid": "14916",
      "name": "My Workspace"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved organization export object. OrganizationExportObjectResponse
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Portfolios

A 'portfolio' gives a high-level overview of the status of multiple initiatives in Asana. Portfolios provide a dashboard overview of the state of multiple projects, including a progress report and the most recent project status update. Portfolios can have a maximum of 250 items in them, and a maximum of 20 custom fields.

Get a list of the portfolios

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/portfolios \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/portfolios");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/portfolios", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/portfolios")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /portfolios

Returns a list of the portfolios in compact representation that are owned by the current API user.

Parameters

Name In Type Required Description
workspace query string false The workspace or organization to filter portfolios on.
owner query string false The user who owns the portfolio. Currently, API users can only get a list of portfolios that they themselves own.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "portfolio",
      "name": "Bug Task"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved portfolios. PortfolioArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a new portfolio

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/portfolios \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Bug Task","resource_type":"portfolio","color":"light-green","workspace":{"name":"Bug Task"},"members":{"data":[{"name":"Greg Sanchez"}]}}}'
var data = JSON.stringify({
  "data": {
    "name": "Bug Task",
    "resource_type": "portfolio",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "name": "Greg Sanchez"
        }
      ]
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/portfolios");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/portfolios", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/portfolios")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /portfolios

Creates a new portfolio in the given workspace with the supplied name.

Note that portfolios created in the Asana UI may have some state (like the “Priority” custom field) which is automatically added to the portfolio when it is created. Portfolios created via our API will not be created with the same initial state to allow integrations to create their own starting state on a portfolio.

Body parameter

{
  "data": {
    "name": "Bug Task",
    "resource_type": "portfolio",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "name": "Greg Sanchez"
        }
      ]
    }
  }
}

Parameters

Name In Type Required Description
body body PortfolioObject true The portfolio to create.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "portfolio",
      "name": "Bug Task"
    }
  ]
}

Responses

Status Meaning Description Schema
201 Created Successfully retrieved portfolios. PortfolioArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a portfolio

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/portfolios/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/portfolios/12345");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/portfolios/12345", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/portfolios/12345")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /portfolios/{portfolio_gid}

Returns the complete portfolio record for a single portfolio.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "portfolio",
    "name": "Bug Task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "color": "light-green",
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested portfolio. PortfolioObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a portfolio

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/portfolios/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Bug Task","resource_type":"portfolio","color":"light-green","workspace":{"name":"Bug Task"},"members":{"data":[{"name":"Greg Sanchez"}]}}}'
var data = JSON.stringify({
  "data": {
    "name": "Bug Task",
    "resource_type": "portfolio",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "name": "Greg Sanchez"
        }
      ]
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/portfolios/12345");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/portfolios/12345", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/portfolios/12345")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Bug Task\",\"resource_type\":\"portfolio\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"},\"members\":{\"data\":[{\"name\":\"Greg Sanchez\"}]}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /portfolios/{portfolio_gid}

An existing portfolio can be updated by making a PUT request on the URL for that portfolio. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged.

Returns the complete updated portfolio record.

Body parameter

{
  "data": {
    "name": "Bug Task",
    "resource_type": "portfolio",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "name": "Greg Sanchez"
        }
      ]
    }
  }
}

Parameters

Name In Type Required Description
body body PortfolioObject true The updated fields for the portfolio.
portfolio_gid path string true Globally unique identifier for the portfolio.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "portfolio",
    "name": "Bug Task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "color": "light-green",
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully updated the portfolio. PortfolioObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a portfolio

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/portfolios/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/portfolios/12345");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/portfolios/12345", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/portfolios/12345")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /portfolios/{portfolio_gid}

An existing portfolio can be deleted by making a DELETE request on the URL for that portfolio.

Returns an empty data record.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully deleted the specified portfolio. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get portfolio items

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/portfolios/12345/items \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/portfolios/12345/items");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345/items",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/portfolios/12345/items", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/portfolios/12345/items")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345/items")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345/items");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /portfolios/{portfolio_gid}/items

Get a list of the items (projects) in compact form in a portfolio.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy",
      "created_at": "2012-02-22T02:06:58.147Z",
      "archived": false,
      "color": "light-green",
      "current_status": {
        "color": "green",
        "text": "Everything is great",
        "author": {
          "id": 12345,
          "name": "Greg Bizarro"
        }
      },
      "custom_fields": [],
      "custom_field_settings": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "is_important": false,
          "parent": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "custom_field": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "resource_subtype": "milestone",
            "type": "text",
            "enum_options": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              }
            ],
            "enum_value": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            },
            "enabled": true,
            "text_value": "Some Value",
            "description": "Development team priority",
            "precision": 2
          }
        }
      ],
      "due_date": "2012-03-26",
      "due_on": "2012-03-26",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "html_notes": "These are things we need to purchase.",
      "is_template": false,
      "layout": "list",
      "members": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "These are things we need to purchase.",
      "owner": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "public": false,
      "section_migration_status": "not_migrated",
      "start_on": "2012-03-26",
      "team": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested portfolio's items. ProjectArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a portfolio item

Code samples

curl --request POST \
  --url 'https://app.asana.com/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345/addItem?insert_after=1331&insert_before=1331&item=1331");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

POST /portfolios/{portfolio_gid}/addItem

Add an item (project) to a portfolio. Returns an empty data block.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.
item query string true The item (project) to add to the portfolio.
insert_before query string true An id of an item (project) in this portfolio. The new item will be added before the one specified here. insert_before and insert_after parameters cannot both be specified.
insert_after query string true An id of an item (project) in this portfolio. The new item will be added after the one specified here. insert_before and insert_after parameters cannot both be specified.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the item to the portfolio. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a portfolio item

Code samples

curl --request POST \
  --url 'https://app.asana.com/api/1.0/portfolios/12345/removeItem?item=1331' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/portfolios/12345/removeItem?item=1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345/removeItem?item=1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/portfolios/12345/removeItem?item=1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/portfolios/12345/removeItem?item=1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345/removeItem?item=1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345/removeItem?item=1331");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

POST /portfolios/{portfolio_gid}/removeItem

Remove an item (project) from a portfolio. Returns an empty data block.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.
item query string true The item (project) to remove from the portfolio.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the item to the portfolio. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a custom field to a portfolio

Code samples

curl --request POST \
  --url 'https://app.asana.com/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345/addCustomFieldSetting?custom_field=14916");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

POST /portfolios/{portfolio_gid}/addCustomFieldSetting

Custom fields are associated with portfolios by way of custom field settings. This method creates a setting for the portfolio.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
custom_field query integer true The custom field to associate with this portfolio.
is_important query boolean false Whether this field should be considered important to this portfolio (for instance, to display in the list view of items in the portfolio).
insert_before query integer false An id of a Custom Field Setting on this portfolio, before which the new Custom Field Setting will be added. insert_before and insert_after parameters cannot both be specified.
insert_after query integer false An id of a Custom Field Setting on this portfolio, after which the new Custom Field Setting will be added. insert_before and insert_after parameters cannot both be specified.
opt_pretty query boolean false Provides “pretty” output.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the custom field to the portfolio. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a custom field from a portfolio

Code samples

curl --request POST \
  --url 'https://app.asana.com/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/portfolios/12345/removeCustomFieldSetting?custom_field=14916");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

POST /portfolios/{portfolio_gid}/removeCustomFieldSetting

Removes a custom field setting from a portfolio.

Parameters

Name In Type Required Description
portfolio_gid path string true Globally unique identifier for the portfolio.
custom_field query integer true The custom field to remove from this portfolio.
opt_pretty query boolean false Provides “pretty” output.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully removed the custom field from the portfolio. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Projects

A project represents a prioritized list of tasks in Asana or a board with columns of tasks represented as cards. It exists in a single workspace or organization and is accessible to a subset of users in that workspace or organization, depending on its permissions.

Get a project's statuses

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects/321654/project_statuses \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects/321654/project_statuses");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/321654/project_statuses",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects/321654/project_statuses", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects/321654/project_statuses")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/321654/project_statuses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/321654/project_statuses");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects/{project_gid}/project_statuses

Returns the compact project status update records for all updates on the project.

Parameters

Name In Type Required Description
project_gid path integer true The project to get statuses from.

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "title": "Status Update - Jun 15",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "The project is moving forward according to plan...",
      "html-text": "'&lt;body&gt;The project &lt;strong&gt;is&lt;/strong&gt; moving forward according to plan...&lt;/body&gt;'",
      "color": "green"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified project's status updates. ProjectStatusArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a project status

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/projects/321654/project_statuses \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"project":123456,"text":"The project is on track to ship next month!","color":"green"}'
var data = JSON.stringify({
  "project": 123456,
  "text": "The project is on track to ship next month!",
  "color": "green"
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects/321654/project_statuses");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/321654/project_statuses",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"project\":123456,\"text\":\"The project is on track to ship next month!\",\"color\":\"green\"}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"project\":123456,\"text\":\"The project is on track to ship next month!\",\"color\":\"green\"}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects/321654/project_statuses", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects/321654/project_statuses")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"project\":123456,\"text\":\"The project is on track to ship next month!\",\"color\":\"green\"}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/321654/project_statuses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"project\":123456,\"text\":\"The project is on track to ship next month!\",\"color\":\"green\"}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/321654/project_statuses");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"project\":123456,\"text\":\"The project is on track to ship next month!\",\"color\":\"green\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /projects/{project_gid}/project_statuses

Creates a new status update on the project. Returns the full record of the newly created project status update.

Body parameter

{
  "project": 123456,
  "text": "The project is on track to ship next month!",
  "color": "green"
}

Parameters

Name In Type Required Description
body body object true The project status to create.
» project body integer true Globally unique identifier for the project.
» text body string true The text of the project status update.
» color body any true The color to associate with the status update.
project_gid path integer true The project to get statuses from.

Enumerated Values

Parameter Value
» color green
» color yellow
» color red

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "title": "Status Update - Jun 15",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "The project is moving forward according to plan...",
    "html-text": "'&lt;body&gt;The project &lt;strong&gt;is&lt;/strong&gt; moving forward according to plan...&lt;/body&gt;'",
    "color": "green"
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created a new story. ProjectStatusObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a set of projects

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects

Returns the compact project records for some filtered set of projects. Use one or more of the parameters provided to filter the projects returned.

Parameters

Name In Type Required Description
workspace query integer false The workspace or organization to filter projects on.
team query integer false The team to filter projects on.
archived query boolean false Only return projects whose archived field takes on the value of this parameter.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy",
      "created_at": "2012-02-22T02:06:58.147Z",
      "archived": false,
      "color": "light-green",
      "current_status": {
        "color": "green",
        "text": "Everything is great",
        "author": {
          "id": 12345,
          "name": "Greg Bizarro"
        }
      },
      "custom_fields": [],
      "custom_field_settings": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "is_important": false,
          "parent": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "custom_field": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "resource_subtype": "milestone",
            "type": "text",
            "enum_options": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              }
            ],
            "enum_value": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            },
            "enabled": true,
            "text_value": "Some Value",
            "description": "Development team priority",
            "precision": 2
          }
        }
      ],
      "due_date": "2012-03-26",
      "due_on": "2012-03-26",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "html_notes": "These are things we need to purchase.",
      "is_template": false,
      "layout": "list",
      "members": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "These are things we need to purchase.",
      "owner": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "public": false,
      "section_migration_status": "not_migrated",
      "start_on": "2012-03-26",
      "team": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved projects. ProjectArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a new project

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Bug Project","notes":"For tracking pesky bugs.","workspace":1331,"team":14916}}'
var data = JSON.stringify({
  "data": {
    "name": "Bug Project",
    "notes": "For tracking pesky bugs.",
    "workspace": 1331,
    "team": 14916
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Bug Project\",\"notes\":\"For tracking pesky bugs.\",\"workspace\":1331,\"team\":14916}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Bug Project\",\"notes\":\"For tracking pesky bugs.\",\"workspace\":1331,\"team\":14916}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Bug Project\",\"notes\":\"For tracking pesky bugs.\",\"workspace\":1331,\"team\":14916}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Bug Project\",\"notes\":\"For tracking pesky bugs.\",\"workspace\":1331,\"team\":14916}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Bug Project\",\"notes\":\"For tracking pesky bugs.\",\"workspace\":1331,\"team\":14916}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /projects

Create a new project in a workspace or team.

Every project is required to be created in a specific workspace or organization, and this cannot be changed once set. Note that you can use the workspace parameter regardless of whether or not it is an organization.

If the workspace for your project is an organization, you must also supply a team to share the project with.

Returns the full record of the newly created project.

Body parameter

{
  "data": {
    "name": "Bug Project",
    "notes": "For tracking pesky bugs.",
    "workspace": 1331,
    "team": 14916
  }
}

Parameters

Name In Type Required Description
body body object true The project to create.
» data body object false none
»» name body string false The name of the project.
»» notes body string false The description of the project.
»» workspace body integer false The workspace or organization to create the project in.
»» team body integer false If creating in an organization, the specific team to create the project in.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy",
    "created_at": "2012-02-22T02:06:58.147Z",
    "archived": false,
    "color": "light-green",
    "current_status": {
      "color": "green",
      "text": "Everything is great",
      "author": {
        "id": 12345,
        "name": "Greg Bizarro"
      }
    },
    "custom_fields": [],
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "layout": "list",
    "members": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "public": false,
    "section_migration_status": "not_migrated",
    "start_on": "2012-03-26",
    "team": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully retrieved projects. ProjectObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a project

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects/1331 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects/1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects/1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects/1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects/{project_gid}

Returns the complete project record for a single project.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy",
    "created_at": "2012-02-22T02:06:58.147Z",
    "archived": false,
    "color": "light-green",
    "current_status": {
      "color": "green",
      "text": "Everything is great",
      "author": {
        "id": 12345,
        "name": "Greg Bizarro"
      }
    },
    "custom_fields": [],
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "layout": "list",
    "members": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "public": false,
    "section_migration_status": "not_migrated",
    "start_on": "2012-03-26",
    "team": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested project. ProjectObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a project

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/projects/1331 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Stuff to buy","resource_type":"project","archived":false,"color":"light-green","due_date":"2012-03-26","due_on":"2012-03-26","html_notes":"These are things we need to purchase.","is_template":false,"modified_at":"2012-02-22T02:06:58.147Z","notes":"These are things we need to purchase.","owner":{"name":"Greg Sanchez"},"public":false,"start_on":"2012-03-26","team":{"name":"Bug Task"},"workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Stuff to buy",
    "resource_type": "project",
    "archived": false,
    "color": "light-green",
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "name": "Greg Sanchez"
    },
    "public": false,
    "start_on": "2012-03-26",
    "team": {
      "name": "Bug Task"
    },
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/projects/1331");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/projects/1331", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/projects/1331")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /projects/{project_gid}

A specific, existing project can be updated by making a PUT request on the URL for that project. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged.

When using this method, it is best to specify only those fields you wish to change, or else you may overwrite changes made by another user since you last retrieved the task.

Returns the complete updated project record.

Body parameter

{
  "data": {
    "name": "Stuff to buy",
    "resource_type": "project",
    "archived": false,
    "color": "light-green",
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "name": "Greg Sanchez"
    },
    "public": false,
    "start_on": "2012-03-26",
    "team": {
      "name": "Bug Task"
    },
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body ProjectObject true The updated fields for the project.
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy",
    "created_at": "2012-02-22T02:06:58.147Z",
    "archived": false,
    "color": "light-green",
    "current_status": {
      "color": "green",
      "text": "Everything is great",
      "author": {
        "id": 12345,
        "name": "Greg Bizarro"
      }
    },
    "custom_fields": [],
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "layout": "list",
    "members": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "public": false,
    "section_migration_status": "not_migrated",
    "start_on": "2012-03-26",
    "team": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully updated the project. ProjectObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a project

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/projects/1331 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/projects/1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/projects/1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/projects/1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /projects/{project_gid}

A specific, existing project can be deleted by making a DELETE request on the URL for that project.

Returns an empty data record.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully deleted the specified project. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Duplicate a project

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/projects/1331/duplicate \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"New Project Name","team":"12345","include":["members","task_notes"],"schedule_dates":{"should_skip_weekends":true,"due_on":"2019-05-21","start_on":"2019-05-21"}}}'
var data = JSON.stringify({
  "data": {
    "name": "New Project Name",
    "team": "12345",
    "include": [
      "members",
      "task_notes"
    ],
    "schedule_dates": {
      "should_skip_weekends": true,
      "due_on": "2019-05-21",
      "start_on": "2019-05-21"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects/1331/duplicate");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/duplicate",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"New Project Name\",\"team\":\"12345\",\"include\":[\"members\",\"task_notes\"],\"schedule_dates\":{\"should_skip_weekends\":true,\"due_on\":\"2019-05-21\",\"start_on\":\"2019-05-21\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"New Project Name\",\"team\":\"12345\",\"include\":[\"members\",\"task_notes\"],\"schedule_dates\":{\"should_skip_weekends\":true,\"due_on\":\"2019-05-21\",\"start_on\":\"2019-05-21\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects/1331/duplicate", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects/1331/duplicate")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"New Project Name\",\"team\":\"12345\",\"include\":[\"members\",\"task_notes\"],\"schedule_dates\":{\"should_skip_weekends\":true,\"due_on\":\"2019-05-21\",\"start_on\":\"2019-05-21\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/duplicate")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"New Project Name\",\"team\":\"12345\",\"include\":[\"members\",\"task_notes\"],\"schedule_dates\":{\"should_skip_weekends\":true,\"due_on\":\"2019-05-21\",\"start_on\":\"2019-05-21\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/duplicate");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"New Project Name\",\"team\":\"12345\",\"include\":[\"members\",\"task_notes\"],\"schedule_dates\":{\"should_skip_weekends\":true,\"due_on\":\"2019-05-21\",\"start_on\":\"2019-05-21\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /projects/{project_gid}/duplicate

Creates and returns a job that will asynchronously handle the duplication.

Body parameter

{
  "data": {
    "name": "New Project Name",
    "team": "12345",
    "include": [
      "members",
      "task_notes"
    ],
    "schedule_dates": {
      "should_skip_weekends": true,
      "due_on": "2019-05-21",
      "start_on": "2019-05-21"
    }
  }
}

Parameters

Name In Type Required Description
body body object true Describes the duplicate's name and the elements that will be duplicated.
» data body object false none
»» name body string false The name of the new project.
»» team body string false Sets the team of the new project. If team is not defined, the new project will be in the same team as the the original project.
»» include body string false The elements that will be duplicated to the new project. Tasks and project notes are always included.
»» schedule_dates body object false A dictionary of options to auto-shift dates. task_dates must be included to use this option. Requires either start_on or due_on, but not both.
»»» should_skip_weekends body boolean false Determines if the auto-shifted dates should skip weekends.
»»» due_on body string false Sets the last due date in the duplicated project to the given date. The rest of the due dates will be offset by the same amount as the due dates in the original project.
»»» start_on body string false Sets the first start date in the duplicated project to the given date. The rest of the start dates will be offset by the same amount as the start dates in the original project.
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
»» include members
»» include task_notes
»» include task_assignee
»» include task_subtasks
»» include task_attachments
»» include task_dates
»» include task_dependencies
»» include task_followers
»» include task_tags
»» include task_projects

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "status": "in_progress",
    "new_project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "new_task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the job to handle duplication. JobObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a custom field to a project

Code samples

curl --request POST \
  --url 'https://app.asana.com/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/addCustomFieldSetting?custom_field=14916");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

POST /projects/{project_gid}/addCustomFieldSetting

Custom fields are associated with projects by way of custom field settings. This method creates a setting for the project.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
custom_field query integer true The custom field to associate with this project.
is_important query boolean false Whether this field should be considered "important" to this project. This may cause it to be displayed more prominently, for example in the task grid.
insert_before query integer false An id of a Custom Field Setting on this project, before which the new Custom Field Setting will be added. insert_before and insert_after parameters cannot both be specified.
insert_after query integer false An id of a Custom Field Setting on this project, after which the new Custom Field Setting will be added. insert_before and insert_after parameters cannot both be specified.
opt_pretty query boolean false Provides “pretty” output.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the custom field to the project. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a custom field from a project

Code samples

curl --request POST \
  --url 'https://app.asana.com/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/removeCustomFieldSetting?custom_field=14916");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

POST /projects/{project_gid}/removeCustomFieldSetting

Removes a custom field setting from a project.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
custom_field query integer true The custom field to remove from this project.
opt_pretty query boolean false Provides “pretty” output.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully removed the custom field from the project. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a team's projects

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/teams/159874/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/teams/159874/projects");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/teams/159874/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/teams/159874/projects", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/teams/159874/projects")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/teams/159874/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/teams/159874/projects");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /teams/{team_gid}/projects

Returns the compact project records for all projects in the team.

Parameters

Name In Type Required Description
archived query boolean false Only return projects whose archived field takes on the value of this parameter.
team_gid path string true Globally unique identifier for the team.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy",
      "created_at": "2012-02-22T02:06:58.147Z",
      "archived": false,
      "color": "light-green",
      "current_status": {
        "color": "green",
        "text": "Everything is great",
        "author": {
          "id": 12345,
          "name": "Greg Bizarro"
        }
      },
      "custom_fields": [],
      "custom_field_settings": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "is_important": false,
          "parent": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "custom_field": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "resource_subtype": "milestone",
            "type": "text",
            "enum_options": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              }
            ],
            "enum_value": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            },
            "enabled": true,
            "text_value": "Some Value",
            "description": "Development team priority",
            "precision": 2
          }
        }
      ],
      "due_date": "2012-03-26",
      "due_on": "2012-03-26",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "html_notes": "These are things we need to purchase.",
      "is_template": false,
      "layout": "list",
      "members": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "These are things we need to purchase.",
      "owner": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "public": false,
      "section_migration_status": "not_migrated",
      "start_on": "2012-03-26",
      "team": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested team's projects. ProjectArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a project in a team

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/teams/159874/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Stuff to buy","resource_type":"project","archived":false,"color":"light-green","due_date":"2012-03-26","due_on":"2012-03-26","html_notes":"These are things we need to purchase.","is_template":false,"modified_at":"2012-02-22T02:06:58.147Z","notes":"These are things we need to purchase.","owner":{"name":"Greg Sanchez"},"public":false,"start_on":"2012-03-26","team":{"name":"Bug Task"},"workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Stuff to buy",
    "resource_type": "project",
    "archived": false,
    "color": "light-green",
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "name": "Greg Sanchez"
    },
    "public": false,
    "start_on": "2012-03-26",
    "team": {
      "name": "Bug Task"
    },
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/teams/159874/projects");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/teams/159874/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/teams/159874/projects", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/teams/159874/projects")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/teams/159874/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/teams/159874/projects");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /teams/{team_gid}/projects

Creates a project shared with the given team.

Returns the full record of the newly created project.

Body parameter

{
  "data": {
    "name": "Stuff to buy",
    "resource_type": "project",
    "archived": false,
    "color": "light-green",
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "name": "Greg Sanchez"
    },
    "public": false,
    "start_on": "2012-03-26",
    "team": {
      "name": "Bug Task"
    },
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body ProjectObject true The new project to create.
team_gid path string true Globally unique identifier for the team.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy",
    "created_at": "2012-02-22T02:06:58.147Z",
    "archived": false,
    "color": "light-green",
    "current_status": {
      "color": "green",
      "text": "Everything is great",
      "author": {
        "id": 12345,
        "name": "Greg Bizarro"
      }
    },
    "custom_fields": [],
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "layout": "list",
    "members": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "public": false,
    "section_migration_status": "not_migrated",
    "start_on": "2012-03-26",
    "team": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the specified project. ProjectObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get all projects in a workspace

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces/12345/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/12345/projects");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/12345/projects", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/12345/projects")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/projects");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}/projects

Returns the compact project records for all projects in the workspace.

Parameters

Name In Type Required Description
archived query boolean false Only return projects whose archived field takes on the value of this parameter.
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy",
      "created_at": "2012-02-22T02:06:58.147Z",
      "archived": false,
      "color": "light-green",
      "current_status": {
        "color": "green",
        "text": "Everything is great",
        "author": {
          "id": 12345,
          "name": "Greg Bizarro"
        }
      },
      "custom_fields": [],
      "custom_field_settings": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "is_important": false,
          "parent": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "custom_field": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "resource_subtype": "milestone",
            "type": "text",
            "enum_options": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              }
            ],
            "enum_value": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            },
            "enabled": true,
            "text_value": "Some Value",
            "description": "Development team priority",
            "precision": 2
          }
        }
      ],
      "due_date": "2012-03-26",
      "due_on": "2012-03-26",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "html_notes": "These are things we need to purchase.",
      "is_template": false,
      "layout": "list",
      "members": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "These are things we need to purchase.",
      "owner": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "public": false,
      "section_migration_status": "not_migrated",
      "start_on": "2012-03-26",
      "team": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested workspace's projects. ProjectArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a project in a workspace

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/workspaces/12345/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Stuff to buy","resource_type":"project","archived":false,"color":"light-green","due_date":"2012-03-26","due_on":"2012-03-26","html_notes":"These are things we need to purchase.","is_template":false,"modified_at":"2012-02-22T02:06:58.147Z","notes":"These are things we need to purchase.","owner":{"name":"Greg Sanchez"},"public":false,"start_on":"2012-03-26","team":{"name":"Bug Task"},"workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Stuff to buy",
    "resource_type": "project",
    "archived": false,
    "color": "light-green",
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "name": "Greg Sanchez"
    },
    "public": false,
    "start_on": "2012-03-26",
    "team": {
      "name": "Bug Task"
    },
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/workspaces/12345/projects");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/workspaces/12345/projects", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/workspaces/12345/projects")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/projects");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /workspaces/{workspace_gid}/projects

Returns the compact project records for all projects in the workspace.

If the workspace for your project is an organization, you must also supply a team to share the project with.

Returns the full record of the newly created project.

Body parameter

{
  "data": {
    "name": "Stuff to buy",
    "resource_type": "project",
    "archived": false,
    "color": "light-green",
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "name": "Greg Sanchez"
    },
    "public": false,
    "start_on": "2012-03-26",
    "team": {
      "name": "Bug Task"
    },
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body ProjectObject true The new project to create.
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy",
    "created_at": "2012-02-22T02:06:58.147Z",
    "archived": false,
    "color": "light-green",
    "current_status": {
      "color": "green",
      "text": "Everything is great",
      "author": {
        "id": 12345,
        "name": "Greg Bizarro"
      }
    },
    "custom_fields": [],
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "layout": "list",
    "members": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "public": false,
    "section_migration_status": "not_migrated",
    "start_on": "2012-03-26",
    "team": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created a new project in the specified workspace. ProjectObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Project Memberships

With the introduction of “comment-only” projects in Asana, a user’s membership in a project comes with associated permissions. These permissions (whether a user has full access to the project or comment-only access) are accessible through the project memberships endpoints described here.

Get the project memberships for a project

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects/1331/project_memberships \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects/1331/project_memberships");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/project_memberships",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects/1331/project_memberships", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects/1331/project_memberships")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/project_memberships")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/project_memberships");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects/{project_gid}/project_memberships

Returns the compact project membership records for the project.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
user query any false The user to filter results on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "user": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "write_access": "full_write"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested project's memberships. ProjectMembershipArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a project membership

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/project_memberships/1331 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/project_memberships/1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/project_memberships/1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/project_memberships/1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/project_memberships/1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/project_memberships/1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/project_memberships/1331");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /project_memberships/{project_gid}

Returns the complete project record for a single project membership.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "user": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "write_access": "full_write"
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested project membership. ProjectMembershipObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Project Statuses

A project status is an update on the progress of a particular project, and is sent out to all project followers when created. These updates include both text describing the update and a color code intended to represent the overall state of the project: “green” for projects that are on track, “yellow” for projects at risk, and “red” for projects that are behind.

Get a project status

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/project_statuses/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/project_statuses/321654");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/project_statuses/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/project_statuses/321654", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/project_statuses/321654")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/project_statuses/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/project_statuses/321654");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /project_statuses/{project_status_gid}

Returns the complete record for a single status update.

Parameters

Name In Type Required Description
project_gid path integer true The project to get statuses from.
project_status_gid path integer true The project status update to get.

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "title": "Status Update - Jun 15",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "The project is moving forward according to plan...",
    "html-text": "'&lt;body&gt;The project &lt;strong&gt;is&lt;/strong&gt; moving forward according to plan...&lt;/body&gt;'",
    "color": "green"
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified project's status updates. ProjectStatusObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a project status

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/project_statuses/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/project_statuses/321654");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/project_statuses/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/project_statuses/321654", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/project_statuses/321654")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/project_statuses/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/project_statuses/321654");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /project_statuses/{project_status_gid}

Deletes a specific, existing project status update.

Returns an empty data record.

Parameters

Name In Type Required Description
project_gid path integer true The project to get statuses from.
project_status_gid path integer true The project status update to get.

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully deleted the specified product status. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Sections

A section is a subdivision of a project that groups tasks together.

Get all sections in a project

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects/1331/sections \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects/1331/sections");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/sections",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects/1331/sections", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects/1331/sections")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/sections")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/sections");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects/{project_gid}/sections

Returns the compact records for all sections in the specified project.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions",
      "created_at": "2012-02-22T02:06:58.147Z",
      "projects": {
        "data": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy",
            "created_at": "2012-02-22T02:06:58.147Z",
            "archived": false,
            "color": "light-green",
            "current_status": {
              "color": "green",
              "text": "Everything is great",
              "author": {
                "id": 12345,
                "name": "Greg Bizarro"
              }
            },
            "custom_fields": [],
            "custom_field_settings": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "project": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "project",
                  "name": "Stuff to buy"
                },
                "is_important": false,
                "parent": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "project",
                  "name": "Stuff to buy"
                },
                "custom_field": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "resource_subtype": "milestone",
                  "type": "text",
                  "enum_options": [
                    {}
                  ],
                  "enum_value": {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Low",
                    "enabled": true,
                    "color": "blue"
                  },
                  "enabled": true,
                  "text_value": "Some Value",
                  "description": "Development team priority",
                  "precision": 2
                }
              }
            ],
            "due_date": "2012-03-26",
            "due_on": "2012-03-26",
            "followers": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Greg Sanchez",
                "email": "gsanchez@example.com",
                "photo": {
                  "image_21x21": "https://...",
                  "image_27x27": "https://...",
                  "image_36x36": "https://...",
                  "image_60x60": "https://...",
                  "image_128x128": "https://..."
                },
                "workspaces": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Bug Task",
                    "email_domains": [],
                    "is_organization": false
                  }
                ]
              }
            ],
            "html_notes": "These are things we need to purchase.",
            "is_template": false,
            "layout": "list",
            "members": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Greg Sanchez",
                "email": "gsanchez@example.com",
                "photo": {
                  "image_21x21": "https://...",
                  "image_27x27": "https://...",
                  "image_36x36": "https://...",
                  "image_60x60": "https://...",
                  "image_128x128": "https://..."
                },
                "workspaces": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Bug Task",
                    "email_domains": [],
                    "is_organization": false
                  }
                ]
              }
            ],
            "modified_at": "2012-02-22T02:06:58.147Z",
            "notes": "These are things we need to purchase.",
            "owner": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez"
            },
            "public": false,
            "section_migration_status": "not_migrated",
            "start_on": "2012-03-26",
            "team": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task"
            },
            "workspace": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task"
            }
          }
        ]
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved sections in project. SectionArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Creates a section in a project

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/projects/1331/sections \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"project":13579,"name":"Next Actions"}'
var data = JSON.stringify({
  "project": 13579,
  "name": "Next Actions"
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects/1331/sections");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/sections",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"project\":13579,\"name\":\"Next Actions\"}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"project\":13579,\"name\":\"Next Actions\"}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects/1331/sections", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects/1331/sections")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"project\":13579,\"name\":\"Next Actions\"}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/sections")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"project\":13579,\"name\":\"Next Actions\"}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/sections");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"project\":13579,\"name\":\"Next Actions\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /projects/{project_gid}/sections

Creates a new section in a project. Returns the full record of the newly created section.

Body parameter

{
  "project": 13579,
  "name": "Next Actions"
}

Parameters

Name In Type Required Description
body body object true The section to create.
» project body integer true The project to create the section in
» name body string true The text to be displayed as the section name. This cannot be an empty string.
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Next Actions",
    "created_at": "2012-02-22T02:06:58.147Z",
    "projects": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy",
          "created_at": "2012-02-22T02:06:58.147Z",
          "archived": false,
          "color": "light-green",
          "current_status": {
            "color": "green",
            "text": "Everything is great",
            "author": {
              "id": 12345,
              "name": "Greg Bizarro"
            }
          },
          "custom_fields": [],
          "custom_field_settings": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "project": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "is_important": false,
              "parent": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "custom_field": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Bug Task",
                "resource_subtype": "milestone",
                "type": "text",
                "enum_options": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Low",
                    "enabled": true,
                    "color": "blue"
                  }
                ],
                "enum_value": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Low",
                  "enabled": true,
                  "color": "blue"
                },
                "enabled": true,
                "text_value": "Some Value",
                "description": "Development team priority",
                "precision": 2
              }
            }
          ],
          "due_date": "2012-03-26",
          "due_on": "2012-03-26",
          "followers": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "html_notes": "These are things we need to purchase.",
          "is_template": false,
          "layout": "list",
          "members": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "modified_at": "2012-02-22T02:06:58.147Z",
          "notes": "These are things we need to purchase.",
          "owner": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez"
          },
          "public": false,
          "section_migration_status": "not_migrated",
          "start_on": "2012-03-26",
          "team": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          },
          "workspace": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          }
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the specified section. SectionObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a section

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/sections/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/sections/321654");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/sections/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/sections/321654", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/sections/321654")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/sections/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/sections/321654");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /sections/{section_gid}

Returns the complete record for a single section.

Parameters

Name In Type Required Description
section_gid path string true The globally unique identified for the section.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Next Actions",
    "created_at": "2012-02-22T02:06:58.147Z",
    "projects": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy",
          "created_at": "2012-02-22T02:06:58.147Z",
          "archived": false,
          "color": "light-green",
          "current_status": {
            "color": "green",
            "text": "Everything is great",
            "author": {
              "id": 12345,
              "name": "Greg Bizarro"
            }
          },
          "custom_fields": [],
          "custom_field_settings": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "project": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "is_important": false,
              "parent": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "custom_field": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Bug Task",
                "resource_subtype": "milestone",
                "type": "text",
                "enum_options": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Low",
                    "enabled": true,
                    "color": "blue"
                  }
                ],
                "enum_value": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Low",
                  "enabled": true,
                  "color": "blue"
                },
                "enabled": true,
                "text_value": "Some Value",
                "description": "Development team priority",
                "precision": 2
              }
            }
          ],
          "due_date": "2012-03-26",
          "due_on": "2012-03-26",
          "followers": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "html_notes": "These are things we need to purchase.",
          "is_template": false,
          "layout": "list",
          "members": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "modified_at": "2012-02-22T02:06:58.147Z",
          "notes": "These are things we need to purchase.",
          "owner": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez"
          },
          "public": false,
          "section_migration_status": "not_migrated",
          "start_on": "2012-03-26",
          "team": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          },
          "workspace": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          }
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved section. SectionObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a section

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/sections/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Next Actions","projects":{"data":[{"name":"Stuff to buy","resource_type":"project","archived":false,"color":"light-green","due_date":"2012-03-26","due_on":"2012-03-26","html_notes":"These are things we need to purchase.","is_template":false,"modified_at":"2012-02-22T02:06:58.147Z","notes":"These are things we need to purchase.","owner":{"name":"Greg Sanchez"},"public":false,"start_on":"2012-03-26","team":{"name":"Bug Task"},"workspace":{"name":"Bug Task"}}]}}}'
var data = JSON.stringify({
  "data": {
    "name": "Next Actions",
    "projects": {
      "data": [
        {
          "name": "Stuff to buy",
          "resource_type": "project",
          "archived": false,
          "color": "light-green",
          "due_date": "2012-03-26",
          "due_on": "2012-03-26",
          "html_notes": "These are things we need to purchase.",
          "is_template": false,
          "modified_at": "2012-02-22T02:06:58.147Z",
          "notes": "These are things we need to purchase.",
          "owner": {
            "name": "Greg Sanchez"
          },
          "public": false,
          "start_on": "2012-03-26",
          "team": {
            "name": "Bug Task"
          },
          "workspace": {
            "name": "Bug Task"
          }
        }
      ]
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/sections/321654");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/sections/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Next Actions\",\"projects\":{\"data\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}]}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Next Actions\",\"projects\":{\"data\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}]}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/sections/321654", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/sections/321654")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Next Actions\",\"projects\":{\"data\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}]}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/sections/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Next Actions\",\"projects\":{\"data\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}]}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/sections/321654");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Next Actions\",\"projects\":{\"data\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\",\"archived\":false,\"color\":\"light-green\",\"due_date\":\"2012-03-26\",\"due_on\":\"2012-03-26\",\"html_notes\":\"These are things we need to purchase.\",\"is_template\":false,\"modified_at\":\"2012-02-22T02:06:58.147Z\",\"notes\":\"These are things we need to purchase.\",\"owner\":{\"name\":\"Greg Sanchez\"},\"public\":false,\"start_on\":\"2012-03-26\",\"team\":{\"name\":\"Bug Task\"},\"workspace\":{\"name\":\"Bug Task\"}}]}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /sections/{section_gid}

A specific, existing section can be updated by making a PUT request on the URL for that project. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged. (note that at this time, the only field that can be updated is the name field.)

When using this method, it is best to specify only those fields you wish to change, or else you may overwrite changes made by another user since you last retrieved the task.

Returns the complete updated section record.

Body parameter

{
  "data": {
    "name": "Next Actions",
    "projects": {
      "data": [
        {
          "name": "Stuff to buy",
          "resource_type": "project",
          "archived": false,
          "color": "light-green",
          "due_date": "2012-03-26",
          "due_on": "2012-03-26",
          "html_notes": "These are things we need to purchase.",
          "is_template": false,
          "modified_at": "2012-02-22T02:06:58.147Z",
          "notes": "These are things we need to purchase.",
          "owner": {
            "name": "Greg Sanchez"
          },
          "public": false,
          "start_on": "2012-03-26",
          "team": {
            "name": "Bug Task"
          },
          "workspace": {
            "name": "Bug Task"
          }
        }
      ]
    }
  }
}

Parameters

Name In Type Required Description
body body SectionObject true The section to create.
section_gid path string true The globally unique identified for the section.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Next Actions",
    "created_at": "2012-02-22T02:06:58.147Z",
    "projects": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy",
          "created_at": "2012-02-22T02:06:58.147Z",
          "archived": false,
          "color": "light-green",
          "current_status": {
            "color": "green",
            "text": "Everything is great",
            "author": {
              "id": 12345,
              "name": "Greg Bizarro"
            }
          },
          "custom_fields": [],
          "custom_field_settings": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "project": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "is_important": false,
              "parent": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "custom_field": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Bug Task",
                "resource_subtype": "milestone",
                "type": "text",
                "enum_options": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Low",
                    "enabled": true,
                    "color": "blue"
                  }
                ],
                "enum_value": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Low",
                  "enabled": true,
                  "color": "blue"
                },
                "enabled": true,
                "text_value": "Some Value",
                "description": "Development team priority",
                "precision": 2
              }
            }
          ],
          "due_date": "2012-03-26",
          "due_on": "2012-03-26",
          "followers": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "html_notes": "These are things we need to purchase.",
          "is_template": false,
          "layout": "list",
          "members": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "modified_at": "2012-02-22T02:06:58.147Z",
          "notes": "These are things we need to purchase.",
          "owner": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez"
          },
          "public": false,
          "section_migration_status": "not_migrated",
          "start_on": "2012-03-26",
          "team": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          },
          "workspace": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          }
        }
      ]
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully updated the specified section. SectionObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a section

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/sections/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/sections/321654");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/sections/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/sections/321654", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/sections/321654")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/sections/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/sections/321654");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /sections/{section_gid}

A specific, existing section can be deleted by making a DELETE request on the URL for that section.

Note that sections must be empty to be deleted.

The last remaining section in a board view cannot be deleted.

Returns an empty data block.

Parameters

Name In Type Required Description
section_gid path string true The globally unique identified for the section.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully deleted the specified section. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add task to section

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/sections/321654/addTask \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"task":123456,"insert_before":86420,"insert_after":987654}'
var data = JSON.stringify({
  "task": 123456,
  "insert_before": 86420,
  "insert_after": 987654
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/sections/321654/addTask");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/sections/321654/addTask",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"task\":123456,\"insert_before\":86420,\"insert_after\":987654}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"task\":123456,\"insert_before\":86420,\"insert_after\":987654}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/sections/321654/addTask", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/sections/321654/addTask")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"task\":123456,\"insert_before\":86420,\"insert_after\":987654}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/sections/321654/addTask")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"task\":123456,\"insert_before\":86420,\"insert_after\":987654}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/sections/321654/addTask");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"task\":123456,\"insert_before\":86420,\"insert_after\":987654}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /sections/{section_gid}/addTask

Add a task to a specific, existing section. This is remove the task from other sections of the project.

The task will be inserted at the top of a section unless an insert_before or insert_after parameter is declared.

This does not work for separators (tasks with the resource_subtype of section).

Body parameter

{
  "task": 123456,
  "insert_before": 86420,
  "insert_after": 987654
}

Parameters

Name In Type Required Description
body body object true The task and optionally the insert location.
» task body string true The task to add to this section.
» insert_before body string true An existing task within this section before which the added task should be inserted. Cannot be provided together with insert_after.
» insert_after body string true An existing task within this section after which the added task should be inserted. Cannot be provided together with insert_before.
section_gid path string true The globally unique identified for the section.

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Move sections

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/projects/1331/sections/insert \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"project":123456,"section":321654,"before_section":86420,"after_section":987654}'
var data = JSON.stringify({
  "project": 123456,
  "section": 321654,
  "before_section": 86420,
  "after_section": 987654
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/projects/1331/sections/insert");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/sections/insert",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"project\":123456,\"section\":321654,\"before_section\":86420,\"after_section\":987654}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"project\":123456,\"section\":321654,\"before_section\":86420,\"after_section\":987654}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/projects/1331/sections/insert", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/projects/1331/sections/insert")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"project\":123456,\"section\":321654,\"before_section\":86420,\"after_section\":987654}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/sections/insert")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"project\":123456,\"section\":321654,\"before_section\":86420,\"after_section\":987654}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/sections/insert");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"project\":123456,\"section\":321654,\"before_section\":86420,\"after_section\":987654}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /projects/{project_gid}/sections/insert

Move sections relative to each other in a board view. One of before_section or after_section is required.

Sections cannot be moved between projects.

At this point in time, moving sections is not supported in list views, only board views.

Returns an empty data block.

Body parameter

{
  "project": 123456,
  "section": 321654,
  "before_section": 86420,
  "after_section": 987654
}

Parameters

Name In Type Required Description
body body object true The section's move action.
» project body integer true The project in which to reorder the given section.
» section body integer true The section to reorder.
» before_section body integer true Insert the given section immediately before the section specified by this parameter.
» after_section body integer true Insert the given section immediately after the section specified by this parameter.
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully moved the specified section. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get tasks in a section

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/sections/321654/tasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/sections/321654/tasks");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/sections/321654/tasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/sections/321654/tasks", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/sections/321654/tasks")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/sections/321654/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/sections/321654/tasks");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /sections/{section_gid}/tasks

Board view only: Returns the compact section records for all tasks within the given section.

Parameters

Name In Type Required Description
section_gid path string true The globally unique identified for the section.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the section's tasks. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Query for tasks in a workspace

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces/12345/tasks/search \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/12345/tasks/search");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/tasks/search",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/12345/tasks/search", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/12345/tasks/search")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/tasks/search")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/tasks/search");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}/tasks/search

To mirror the functionality of the Asana web app's advanced search feature, the Asana API has a task search endpoint that allows you to build complex filters to find and retrieve the exact data you need.

Custom fields

| Parameter name | Custom field type | Accepted type | |---|---|---| | custom_fields.<id>.is_set | All | Boolean | | custom_fields.<id>.value | Text | String | | custom_fields.<id>.value | Number | Number | | custom_fields.<id>.value | Enum | Enum option ID | | custom_fields.<id>.starts_with | Text only | String | | custom_fields.<id>.ends_with | Text only | String | | custom_fields.<id>.contains | Text only | String | | custom_fields.<id>.less_than | Number only | Number | | custom_fields.<id>.greater_than | Number only | Number | For example, if the ID of the custom field is 12345, these query parameter to find tasks where it is set would be custom_fields.12345.is_set=true. To match an exact value for an enum custom field, use the ID of the desired enum option and not the name of the enum option: custom_fields.12345.value=67890. Searching for multiple exact matches of a custom field is not supported.

Premium access

Like the Asana web product's advance search feature, this search endpoint will only be available to premium Asana users. A user is premium if any of the following is true: - The workspace in which the search is being performed is a premium workspace - The user is a member of a premium team inside the workspace Even if a user is only a member of a premium team inside a non-premium workspace, search will allow them to find data anywhere in the workspace, not just inside the premium team. Making a search request using credentials of a non-premium user will result in a 402 Payment Required error.

Pagination

Search results are not stable; repeating the same query multiple times may return the data in a different order, even if the data do not change. Because of this, the traditional pagination available elsewhere in the Asana API is not available here. However, you can paginate manually by sorting the search results by their creation time and then modifying each subsequent query to exclude data you have already seen. Page sizes are limited to a maximum of 100 items, and can be specified by the limit query parameter.

Eventual consistency

Changes in Asana (regardless of whether they’re made though the web product or the API) are forwarded to our search infrastructure to be indexed. This process can take between 10 and 60 seconds to complete under normal operation, and longer during some production incidents. Making a change to a task that would alter its presence in a particular search query will not be reflected immediately. This is also true of the advanced search feature in the web product.

Rate limits

You may receive a 429 Too Many Requests response if you hit any of our rate limits.

Parameters

Name In Type Required Description
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.
text undefined string false Performs full-text search on both task name and description
resource_subtype undefined string false Filters results by the task's resource_subtype
assignee.any query string false none
assignee.not query string false none
assignee_status query string false none
projects.any query string false none
projects.not query string false none
projects.all query string false none
sections.any query string false none
sections.not query string false none
sections.all query string false none
tags.any query string false none
tags.not query string false none
tags.all query string false none
teams.any query string false none
followers.any query string false none
followers.not query string false none
created_by.any query string false none
created_by.not query string false none
assigned_by.any query string false none
assigned_by.not query string false none
liked_by.any query string false none
liked_by.not query string false none
commented_on_by.any query string false none
commented_on_by.not query string false none
due_on.before query string(date) false none
due_on.after query string(date) false none
due_on query string(date) false none
due_at.before query string(date-time) false none
due_at.after query string(date-time) false none
start_on.before query string(date) false none
start_on.after query string(date) false none
start_on query string(date) false none
created_on.before query string(date) false none
created_on.after query string(date) false none
created_on query string(date) false none
created_at.before query string(date-time) false none
created_at.after query string(date-time) false none
completed_on.before query string(date) false none
completed_on.after query string(date) false none
completed_on query string(date) false none
completed_at.before query string(date-time) false none
completed_at.after query string(date-time) false none
modified_on.before query string(date) false none
modified_on.after query string(date) false none
modified_on query string(date) false none
modified_at.before query string(date-time) false none
modified_at.after query string(date-time) false none
is_blocking query boolean false none
is_blocked query boolean false none
has_attachment query boolean false none
completed query boolean false none
is_subtask query boolean false none
sort_by query string false none
sort_ascending query boolean false none

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
resource_subtype default_task
resource_subtype milestone
assignee_status inbox
assignee_status today
assignee_status upcoming
assignee_status later
sort_by due_date
sort_by created_at
sort_by completed_at
sort_by likes
sort_by modified_at

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the section's tasks. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Stories

A story represents an activity associated with an object in the Asana system.

Get a task's stories

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654/stories \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654/stories");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/stories",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654/stories", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654/stories")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/stories")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/stories");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/stories

Returns the compact records for all stories on the task.

Parameters

Name In Type Required Description
task_gid path string true The task to get stories from.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "resource_subtype": "milestone",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "marked today",
      "type": "comment",
      "html_text": "Get whatever Sashimi has.",
      "is_edited": false,
      "is_pinned": false,
      "hearted": false,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "num_hearts": 5,
      "liked": false,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "num_likes": 5,
      "previews": [
        {
          "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
          "footer": "Mar 17, 2019 1:25 PM",
          "header": "Asana for Slack",
          "header_link": "https://asana.comn/apps/slack",
          "html_text": "<body>Great! I like this idea.</body>",
          "text": "Great! I like this idea.",
          "title": "Greg",
          "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
        }
      ],
      "old_name": "This was the Old Name",
      "new_name": "This is the New Name",
      "old_dates": {
        "start_on": "2019-09-15",
        "due_at": "2012-02-22T02:06:58.158Z",
        "due_on": "2019-09-15"
      },
      "new_dates": {
        "start_on": "2019-09-15",
        "due_at": "2012-02-22T02:06:58.158Z",
        "due_on": "2019-09-15"
      },
      "old_resource_subtype": "default_task",
      "new_resource_subtype": "milestone",
      "story": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "resource_subtype": "milestone",
        "created_at": "2012-02-22T02:06:58.147Z",
        "created_by": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        },
        "text": "marked today",
        "type": "comment"
      },
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "follower": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "old_section": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Next Actions"
      },
      "new_section": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Next Actions"
      },
      "task": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "tag": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value"
      },
      "old_text_value": "This was the Old Text",
      "new_text_value": "This is the New Text",
      "old_number_value": 1,
      "new_number_value": 2,
      "old_enum_value": null,
      "new_enum_value": null,
      "duplicate_of": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "duplicated_from": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "dependancy": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "source": "web",
      "target": {
        "id": 1234,
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified task's stories. StoryArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a comment on a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/stories \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"task":123456,"text":"This is a comment."}'
var data = JSON.stringify({
  "task": 123456,
  "text": "This is a comment."
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/stories");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/stories",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"task\":123456,\"text\":\"This is a comment.\"}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"task\":123456,\"text\":\"This is a comment.\"}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/stories", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/stories")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"task\":123456,\"text\":\"This is a comment.\"}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/stories")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"task\":123456,\"text\":\"This is a comment.\"}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/stories");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"task\":123456,\"text\":\"This is a comment.\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/stories

Adds a comment to a task. The comment will be authored by the currently authenticated user, and timestamped when the server receives the request.

Returns the full record for the new story added to the task.

Body parameter

{
  "task": 123456,
  "text": "This is a comment."
}

Parameters

Name In Type Required Description
body body object true The comment story to create.
» task body integer true Globally unique identifier for the task.
» text body string true The plain text of the comment to add.
task_gid path string true The task to get stories from.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "marked today",
    "type": "comment",
    "html_text": "Get whatever Sashimi has.",
    "is_edited": false,
    "is_pinned": false,
    "hearted": false,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_hearts": 5,
    "liked": false,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_likes": 5,
    "previews": [
      {
        "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
        "footer": "Mar 17, 2019 1:25 PM",
        "header": "Asana for Slack",
        "header_link": "https://asana.comn/apps/slack",
        "html_text": "<body>Great! I like this idea.</body>",
        "text": "Great! I like this idea.",
        "title": "Greg",
        "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
      }
    ],
    "old_name": "This was the Old Name",
    "new_name": "This is the New Name",
    "old_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "new_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "old_resource_subtype": "default_task",
    "new_resource_subtype": "milestone",
    "story": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "resource_subtype": "milestone",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "marked today",
      "type": "comment"
    },
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "follower": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "old_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "new_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "tag": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy"
    },
    "custom_field": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    },
    "old_text_value": "This was the Old Text",
    "new_text_value": "This is the New Text",
    "old_number_value": 1,
    "new_number_value": 2,
    "old_enum_value": null,
    "new_enum_value": null,
    "duplicate_of": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "duplicated_from": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "dependancy": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "source": "web",
    "target": {
      "id": 1234,
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created a new story. StoryObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a story

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/stories/1234 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/stories/1234");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/stories/1234",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/stories/1234", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/stories/1234")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/stories/1234")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/stories/1234");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /stories/{story_gid}

Returns the full record for a single story.

Parameters

Name In Type Required Description
story_gid path string true The globally unique identifier for the story.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "marked today",
    "type": "comment",
    "html_text": "Get whatever Sashimi has.",
    "is_edited": false,
    "is_pinned": false,
    "hearted": false,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_hearts": 5,
    "liked": false,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_likes": 5,
    "previews": [
      {
        "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
        "footer": "Mar 17, 2019 1:25 PM",
        "header": "Asana for Slack",
        "header_link": "https://asana.comn/apps/slack",
        "html_text": "<body>Great! I like this idea.</body>",
        "text": "Great! I like this idea.",
        "title": "Greg",
        "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
      }
    ],
    "old_name": "This was the Old Name",
    "new_name": "This is the New Name",
    "old_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "new_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "old_resource_subtype": "default_task",
    "new_resource_subtype": "milestone",
    "story": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "resource_subtype": "milestone",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "marked today",
      "type": "comment"
    },
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "follower": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "old_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "new_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "tag": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy"
    },
    "custom_field": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    },
    "old_text_value": "This was the Old Text",
    "new_text_value": "This is the New Text",
    "old_number_value": 1,
    "new_number_value": 2,
    "old_enum_value": null,
    "new_enum_value": null,
    "duplicate_of": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "duplicated_from": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "dependancy": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "source": "web",
    "target": {
      "id": 1234,
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified story. StoryObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a story

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/stories/1234 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"resource_subtype":"milestone","text":"marked today","html_text":"Get whatever Sashimi has.","is_edited":false,"is_pinned":false,"old_name":"This was the Old Name","new_name":"This is the New Name","old_dates":{"start_on":"2019-09-15","due_at":"2012-02-22T02:06:58.158Z","due_on":"2019-09-15"},"new_dates":{"start_on":"2019-09-15","due_at":"2012-02-22T02:06:58.158Z","due_on":"2019-09-15"},"old_resource_subtype":"default_task","new_resource_subtype":"milestone","story":{"resource_subtype":"milestone","text":"marked today"},"assignee":{"name":"Greg Sanchez"},"follower":{"name":"Greg Sanchez"},"old_section":{"name":"Next Actions"},"new_section":{"name":"Next Actions"},"task":{"name":"Bug Task"},"project":{"name":"Stuff to buy","resource_type":"project"},"tag":{"name":"Stuff to buy"},"custom_field":{"name":"Bug Task","resource_subtype":"milestone","type":"text","enum_options":[],"enum_value":{"name":"Low","enabled":true,"color":"blue"},"enabled":true,"text_value":"Some Value"},"old_text_value":"This was the Old Text","new_text_value":"This is the New Text","old_number_value":1,"new_number_value":2,"old_enum_value":null,"new_enum_value":null,"duplicate_of":{"name":"Bug Task"},"duplicated_from":{"name":"Bug Task"},"dependancy":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "resource_subtype": "milestone",
    "text": "marked today",
    "html_text": "Get whatever Sashimi has.",
    "is_edited": false,
    "is_pinned": false,
    "old_name": "This was the Old Name",
    "new_name": "This is the New Name",
    "old_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "new_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "old_resource_subtype": "default_task",
    "new_resource_subtype": "milestone",
    "story": {
      "resource_subtype": "milestone",
      "text": "marked today"
    },
    "assignee": {
      "name": "Greg Sanchez"
    },
    "follower": {
      "name": "Greg Sanchez"
    },
    "old_section": {
      "name": "Next Actions"
    },
    "new_section": {
      "name": "Next Actions"
    },
    "task": {
      "name": "Bug Task"
    },
    "project": {
      "name": "Stuff to buy",
      "resource_type": "project"
    },
    "tag": {
      "name": "Stuff to buy"
    },
    "custom_field": {
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    },
    "old_text_value": "This was the Old Text",
    "new_text_value": "This is the New Text",
    "old_number_value": 1,
    "new_number_value": 2,
    "old_enum_value": null,
    "new_enum_value": null,
    "duplicate_of": {
      "name": "Bug Task"
    },
    "duplicated_from": {
      "name": "Bug Task"
    },
    "dependancy": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/stories/1234");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/stories/1234",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\",\"html_text\":\"Get whatever Sashimi has.\",\"is_edited\":false,\"is_pinned\":false,\"old_name\":\"This was the Old Name\",\"new_name\":\"This is the New Name\",\"old_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"new_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"old_resource_subtype\":\"default_task\",\"new_resource_subtype\":\"milestone\",\"story\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\"},\"assignee\":{\"name\":\"Greg Sanchez\"},\"follower\":{\"name\":\"Greg Sanchez\"},\"old_section\":{\"name\":\"Next Actions\"},\"new_section\":{\"name\":\"Next Actions\"},\"task\":{\"name\":\"Bug Task\"},\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"tag\":{\"name\":\"Stuff to buy\"},\"custom_field\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\"},\"old_text_value\":\"This was the Old Text\",\"new_text_value\":\"This is the New Text\",\"old_number_value\":1,\"new_number_value\":2,\"old_enum_value\":null,\"new_enum_value\":null,\"duplicate_of\":{\"name\":\"Bug Task\"},\"duplicated_from\":{\"name\":\"Bug Task\"},\"dependancy\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\",\"html_text\":\"Get whatever Sashimi has.\",\"is_edited\":false,\"is_pinned\":false,\"old_name\":\"This was the Old Name\",\"new_name\":\"This is the New Name\",\"old_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"new_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"old_resource_subtype\":\"default_task\",\"new_resource_subtype\":\"milestone\",\"story\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\"},\"assignee\":{\"name\":\"Greg Sanchez\"},\"follower\":{\"name\":\"Greg Sanchez\"},\"old_section\":{\"name\":\"Next Actions\"},\"new_section\":{\"name\":\"Next Actions\"},\"task\":{\"name\":\"Bug Task\"},\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"tag\":{\"name\":\"Stuff to buy\"},\"custom_field\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\"},\"old_text_value\":\"This was the Old Text\",\"new_text_value\":\"This is the New Text\",\"old_number_value\":1,\"new_number_value\":2,\"old_enum_value\":null,\"new_enum_value\":null,\"duplicate_of\":{\"name\":\"Bug Task\"},\"duplicated_from\":{\"name\":\"Bug Task\"},\"dependancy\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/stories/1234", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/stories/1234")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\",\"html_text\":\"Get whatever Sashimi has.\",\"is_edited\":false,\"is_pinned\":false,\"old_name\":\"This was the Old Name\",\"new_name\":\"This is the New Name\",\"old_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"new_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"old_resource_subtype\":\"default_task\",\"new_resource_subtype\":\"milestone\",\"story\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\"},\"assignee\":{\"name\":\"Greg Sanchez\"},\"follower\":{\"name\":\"Greg Sanchez\"},\"old_section\":{\"name\":\"Next Actions\"},\"new_section\":{\"name\":\"Next Actions\"},\"task\":{\"name\":\"Bug Task\"},\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"tag\":{\"name\":\"Stuff to buy\"},\"custom_field\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\"},\"old_text_value\":\"This was the Old Text\",\"new_text_value\":\"This is the New Text\",\"old_number_value\":1,\"new_number_value\":2,\"old_enum_value\":null,\"new_enum_value\":null,\"duplicate_of\":{\"name\":\"Bug Task\"},\"duplicated_from\":{\"name\":\"Bug Task\"},\"dependancy\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/stories/1234")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\",\"html_text\":\"Get whatever Sashimi has.\",\"is_edited\":false,\"is_pinned\":false,\"old_name\":\"This was the Old Name\",\"new_name\":\"This is the New Name\",\"old_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"new_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"old_resource_subtype\":\"default_task\",\"new_resource_subtype\":\"milestone\",\"story\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\"},\"assignee\":{\"name\":\"Greg Sanchez\"},\"follower\":{\"name\":\"Greg Sanchez\"},\"old_section\":{\"name\":\"Next Actions\"},\"new_section\":{\"name\":\"Next Actions\"},\"task\":{\"name\":\"Bug Task\"},\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"tag\":{\"name\":\"Stuff to buy\"},\"custom_field\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\"},\"old_text_value\":\"This was the Old Text\",\"new_text_value\":\"This is the New Text\",\"old_number_value\":1,\"new_number_value\":2,\"old_enum_value\":null,\"new_enum_value\":null,\"duplicate_of\":{\"name\":\"Bug Task\"},\"duplicated_from\":{\"name\":\"Bug Task\"},\"dependancy\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/stories/1234");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\",\"html_text\":\"Get whatever Sashimi has.\",\"is_edited\":false,\"is_pinned\":false,\"old_name\":\"This was the Old Name\",\"new_name\":\"This is the New Name\",\"old_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"new_dates\":{\"start_on\":\"2019-09-15\",\"due_at\":\"2012-02-22T02:06:58.158Z\",\"due_on\":\"2019-09-15\"},\"old_resource_subtype\":\"default_task\",\"new_resource_subtype\":\"milestone\",\"story\":{\"resource_subtype\":\"milestone\",\"text\":\"marked today\"},\"assignee\":{\"name\":\"Greg Sanchez\"},\"follower\":{\"name\":\"Greg Sanchez\"},\"old_section\":{\"name\":\"Next Actions\"},\"new_section\":{\"name\":\"Next Actions\"},\"task\":{\"name\":\"Bug Task\"},\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"tag\":{\"name\":\"Stuff to buy\"},\"custom_field\":{\"name\":\"Bug Task\",\"resource_subtype\":\"milestone\",\"type\":\"text\",\"enum_options\":[],\"enum_value\":{\"name\":\"Low\",\"enabled\":true,\"color\":\"blue\"},\"enabled\":true,\"text_value\":\"Some Value\"},\"old_text_value\":\"This was the Old Text\",\"new_text_value\":\"This is the New Text\",\"old_number_value\":1,\"new_number_value\":2,\"old_enum_value\":null,\"new_enum_value\":null,\"duplicate_of\":{\"name\":\"Bug Task\"},\"duplicated_from\":{\"name\":\"Bug Task\"},\"dependancy\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /stories/{story_gid}

Updates the story and returns the full record for the updated story. Only comment stories can have their text updated, and only comment stories and attachment stories can be pinned. Only one of text and html_text can be specified.

Body parameter

{
  "data": {
    "resource_subtype": "milestone",
    "text": "marked today",
    "html_text": "Get whatever Sashimi has.",
    "is_edited": false,
    "is_pinned": false,
    "old_name": "This was the Old Name",
    "new_name": "This is the New Name",
    "old_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "new_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "old_resource_subtype": "default_task",
    "new_resource_subtype": "milestone",
    "story": {
      "resource_subtype": "milestone",
      "text": "marked today"
    },
    "assignee": {
      "name": "Greg Sanchez"
    },
    "follower": {
      "name": "Greg Sanchez"
    },
    "old_section": {
      "name": "Next Actions"
    },
    "new_section": {
      "name": "Next Actions"
    },
    "task": {
      "name": "Bug Task"
    },
    "project": {
      "name": "Stuff to buy",
      "resource_type": "project"
    },
    "tag": {
      "name": "Stuff to buy"
    },
    "custom_field": {
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    },
    "old_text_value": "This was the Old Text",
    "new_text_value": "This is the New Text",
    "old_number_value": 1,
    "new_number_value": 2,
    "old_enum_value": null,
    "new_enum_value": null,
    "duplicate_of": {
      "name": "Bug Task"
    },
    "duplicated_from": {
      "name": "Bug Task"
    },
    "dependancy": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body StoryObject true The comment story to update.
story_gid path string true The globally unique identifier for the story.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "marked today",
    "type": "comment",
    "html_text": "Get whatever Sashimi has.",
    "is_edited": false,
    "is_pinned": false,
    "hearted": false,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_hearts": 5,
    "liked": false,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_likes": 5,
    "previews": [
      {
        "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
        "footer": "Mar 17, 2019 1:25 PM",
        "header": "Asana for Slack",
        "header_link": "https://asana.comn/apps/slack",
        "html_text": "<body>Great! I like this idea.</body>",
        "text": "Great! I like this idea.",
        "title": "Greg",
        "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
      }
    ],
    "old_name": "This was the Old Name",
    "new_name": "This is the New Name",
    "old_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "new_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "old_resource_subtype": "default_task",
    "new_resource_subtype": "milestone",
    "story": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "resource_subtype": "milestone",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "marked today",
      "type": "comment"
    },
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "follower": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "old_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "new_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "tag": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy"
    },
    "custom_field": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    },
    "old_text_value": "This was the Old Text",
    "new_text_value": "This is the New Text",
    "old_number_value": 1,
    "new_number_value": 2,
    "old_enum_value": null,
    "new_enum_value": null,
    "duplicate_of": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "duplicated_from": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "dependancy": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "source": "web",
    "target": {
      "id": 1234,
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified story. StoryObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a story

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/stories/1234 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/stories/1234");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/stories/1234",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/stories/1234", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/stories/1234")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/stories/1234")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/stories/1234");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /stories/{story_gid}

Deletes a story. A user can only delete stories they have created. Returns an empty data record.

Returns an empty data record.

Parameters

Name In Type Required Description
story_gid path string true The globally unique identifier for the story.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully deleted the specified story. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Tags

A tag is a label that can be attached to any task in Asana. It exists in a single workspace or organization.

Get a set of tags

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tags \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tags");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tags",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tags", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tags")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tags")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tags");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tags

Returns the compact tag records for some filtered set of tags. Use one or more of the parameters provided to filter the tags returned.

Parameters

Name In Type Required Description
workspace query integer false The workspace to filter tags on.
archived query boolean false Only return tags whose archived field takes on the value of this parameter.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "color": "light-green",
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified set of tags. TagArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a tag

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tags \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Stuff to buy","color":"light-green","workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Stuff to buy",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tags");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tags",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tags", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tags")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tags")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tags");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tags

Creates a new tag in a workspace or organization.

Every tag is required to be created in a specific workspace or organization, and this cannot be changed once set. Note that you can use the workspace parameter regardless of whether or not it is an organization.

Returns the full record of the newly created tag.

Body parameter

{
  "data": {
    "name": "Stuff to buy",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body TagObject true The tag to create.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Stuff to buy",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "color": "light-green",
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the newly specified tag. TagObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a tag

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tags/11235 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tags/11235");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tags/11235",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tags/11235", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tags/11235")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tags/11235")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tags/11235");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tags/{tag_gid}

Returns the complete tag record for a single tag.

Parameters

Name In Type Required Description
tag_gid path string true Globally unique identifier for the tag.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Stuff to buy",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "color": "light-green",
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified tag. TagObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a tag

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/tags/11235 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/tags/11235");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tags/11235",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/tags/11235", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/tags/11235")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tags/11235")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tags/11235");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

PUT /tags/{tag_gid}

Updates the properties of a tag. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged.

When using this method, it is best to specify only those fields you wish to change, or else you may overwrite changes made by another user since you last retrieved the task.

Returns the complete updated tag record.

Parameters

Name In Type Required Description
tag_gid path string true Globally unique identifier for the tag.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Stuff to buy",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "color": "light-green",
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully updated the specified tag. TagObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get tasks with tag

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tags/11235/tasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tags/11235/tasks");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tags/11235/tasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tags/11235/tasks", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tags/11235/tasks")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tags/11235/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tags/11235/tasks");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tags/{tag_gid}/tasks

Returns the compact task records for all tasks with the given tag. Tasks can have more than one tag at a time.

Parameters

Name In Type Required Description
tag_gid path string true Globally unique identifier for the tag.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the tasks associated with the specified tag. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get tags in a workspace

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces/1331/tags \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/1331/tags");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/1331/tags",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/1331/tags", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/1331/tags")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/1331/tags")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/1331/tags");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}/tags

Returns the compact tag records for some filtered set of tags. Use one or more of the parameters provided to filter the tags returned.

Parameters

Name In Type Required Description
workspace_gid path integer true The workspace to filter tags on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "color": "light-green",
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified set of tags. TagArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a tag in a workspace

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/workspaces/1331/tags \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Stuff to buy","color":"light-green","workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Stuff to buy",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/workspaces/1331/tags");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/1331/tags",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/workspaces/1331/tags", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/workspaces/1331/tags")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/1331/tags")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/1331/tags");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Stuff to buy\",\"color\":\"light-green\",\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /workspaces/{workspace_gid}/tags

Creates a new tag in a workspace or organization.

Every tag is required to be created in a specific workspace or organization, and this cannot be changed once set. Note that you can use the workspace parameter regardless of whether or not it is an organization.

Returns the full record of the newly created tag.

Body parameter

{
  "data": {
    "name": "Stuff to buy",
    "color": "light-green",
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body TagObject true The tag to create.
workspace_gid path integer true The workspace to filter tags on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "color": "light-green",
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified set of tags. TagArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Tasks

The task is the basic object around which many operations in Asana are centered.

Get a project's tasks

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/projects/1331/tasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/projects/1331/tasks");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/projects/1331/tasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/projects/1331/tasks", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/projects/1331/tasks")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/projects/1331/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/projects/1331/tasks");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /projects/{project_gid}/tasks

Returns the compact task records for all tasks within the given project, ordered by their priority within the project. Tasks can exist in more than one project at a time.

Parameters

Name In Type Required Description
project_gid path string true Globally unique identifier for the project.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested project's tasks. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a set of tasks

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks

Returns the compact task records for some filtered set of tasks. Use one or more of the parameters provided to filter the tasks returned. You must specify a project or tag if you do not specify assignee and workspace.

Parameters

Name In Type Required Description
assignee query any false The assignee to filter tasks on.
project query integer false The project to filter tasks on.
section query integer false The section to filter tasks on.
workspace query integer false The workspace to filter tasks on.
completed_since query any false Only return tasks that are either incomplete or that have been completed since this time.
modified_since query any false Only return tasks that have been modified since the given time.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

assignee: The assignee to filter tasks on. Note: If you specify assignee, you must also specify the workspace to filter on.

section: The section to filter tasks on. Note: Currently, this is only supported in board views.

workspace: The workspace to filter tasks on. Note: If you specify workspace, you must also specify the assignee to filter on.

modified_since: Only return tasks that have been modified since the given time.

Note: A task is considered “modified” if any of its properties change, or associations between it and other objects are modified (e.g. a task being added to a project). A task is not considered modified just because another object it is associated with (e.g. a subtask) is modified. Actions that count as modifying the task include assigning, renaming, completing, and adding stories.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved requested tasks. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Buy catnip","resource_subtype":"default_task","assignee":{"name":"Greg Sanchez"},"assignee_status":"upcoming","completed":false,"due_at":"2012-02-22T02:06:58.147Z","due_on":"2012-03-26","external":{"id":"my_id","data":"A blob of information"},"followers":[{"name":"Greg Sanchez"}],"html_notes":"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>","memberships":[{"project":{"name":"Stuff to buy","resource_type":"project"},"section":{"name":"Next Actions"}}],"notes":"Mittens really likes the stuff from Humboldt.","parent":{"name":"Bug Task"},"projects":[{"name":"Stuff to buy","resource_type":"project"}],"start_on":"2012-03-26","tags":[{"id":59746,"gid":"59746","name":"Grade A"}],"workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Buy catnip",
    "resource_subtype": "default_task",
    "assignee": {
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "memberships": [
      {
        "project": {
          "name": "Stuff to buy",
          "resource_type": "project"
        },
        "section": {
          "name": "Next Actions"
        }
      }
    ],
    "notes": "Mittens really likes the stuff from Humboldt.",
    "parent": {
      "name": "Bug Task"
    },
    "projects": [
      {
        "name": "Stuff to buy",
        "resource_type": "project"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks

Creating a new task is as easy as POSTing to the /tasks endpoint with a data block containing the fields you’d like to set on the task. Any unspecified fields will take on default values.

Every task is required to be created in a specific workspace, and this workspace cannot be changed once set. The workspace need not be set explicitly if you specify projects or a parent task instead.

Body parameter

{
  "data": {
    "name": "Buy catnip",
    "resource_subtype": "default_task",
    "assignee": {
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "memberships": [
      {
        "project": {
          "name": "Stuff to buy",
          "resource_type": "project"
        },
        "section": {
          "name": "Next Actions"
        }
      }
    ],
    "notes": "Mittens really likes the stuff from Humboldt.",
    "parent": {
      "name": "Bug Task"
    },
    "projects": [
      {
        "name": "Stuff to buy",
        "resource_type": "project"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body any true The task to create.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Buy catnip",
    "created_at": "2012-02-22T02:06:58.147Z",
    "resource_subtype": "default_task",
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "completed_at": "2012-02-22T02:06:58.147Z",
    "custom_fields": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    ],
    "dependencies": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "dependents": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "hearted": true,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "liked": true,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "memberships": [
      {
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "section": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Next Actions"
        }
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "Mittens really likes the stuff from Humboldt.",
    "num_hearts": 5,
    "num_likes": 5,
    "num_subtasks": 3,
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "projects": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created a new task. TaskObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a task

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}

Returns the complete task record for a single task.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Buy catnip",
    "created_at": "2012-02-22T02:06:58.147Z",
    "resource_subtype": "default_task",
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "completed_at": "2012-02-22T02:06:58.147Z",
    "custom_fields": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    ],
    "dependencies": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "dependents": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "hearted": true,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "liked": true,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "memberships": [
      {
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "section": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Next Actions"
        }
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "Mittens really likes the stuff from Humboldt.",
    "num_hearts": 5,
    "num_likes": 5,
    "num_subtasks": 3,
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "projects": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified task. TaskObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a task

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/tasks/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Buy catnip","resource_subtype":"default_task","assignee":{"name":"Greg Sanchez"},"assignee_status":"upcoming","completed":false,"due_at":"2012-02-22T02:06:58.147Z","due_on":"2012-03-26","external":{"id":"my_id","data":"A blob of information"},"followers":[{"name":"Greg Sanchez"}],"html_notes":"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>","memberships":[{"project":{"name":"Stuff to buy","resource_type":"project"},"section":{"name":"Next Actions"}}],"notes":"Mittens really likes the stuff from Humboldt.","parent":{"name":"Bug Task"},"projects":[{"name":"Stuff to buy","resource_type":"project"}],"start_on":"2012-03-26","tags":[{"id":59746,"gid":"59746","name":"Grade A"}],"workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Buy catnip",
    "resource_subtype": "default_task",
    "assignee": {
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "memberships": [
      {
        "project": {
          "name": "Stuff to buy",
          "resource_type": "project"
        },
        "section": {
          "name": "Next Actions"
        }
      }
    ],
    "notes": "Mittens really likes the stuff from Humboldt.",
    "parent": {
      "name": "Bug Task"
    },
    "projects": [
      {
        "name": "Stuff to buy",
        "resource_type": "project"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/tasks/321654");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/tasks/321654", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/tasks/321654")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /tasks/{task_gid}

A specific, existing task can be updated by making a PUT request on the URL for that task. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged.

When using this method, it is best to specify only those fields you wish to change, or else you may overwrite changes made by another user since you last retrieved the task.

Returns the complete updated task record.

Body parameter

{
  "data": {
    "name": "Buy catnip",
    "resource_subtype": "default_task",
    "assignee": {
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "memberships": [
      {
        "project": {
          "name": "Stuff to buy",
          "resource_type": "project"
        },
        "section": {
          "name": "Next Actions"
        }
      }
    ],
    "notes": "Mittens really likes the stuff from Humboldt.",
    "parent": {
      "name": "Bug Task"
    },
    "projects": [
      {
        "name": "Stuff to buy",
        "resource_type": "project"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body TaskObject true The task to update.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Buy catnip",
    "created_at": "2012-02-22T02:06:58.147Z",
    "resource_subtype": "default_task",
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "completed_at": "2012-02-22T02:06:58.147Z",
    "custom_fields": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    ],
    "dependencies": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "dependents": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "hearted": true,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "liked": true,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "memberships": [
      {
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "section": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Next Actions"
        }
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "Mittens really likes the stuff from Humboldt.",
    "num_hearts": 5,
    "num_likes": 5,
    "num_subtasks": 3,
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "projects": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully updated the specified task. TaskObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Delete a task

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/tasks/321654 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/tasks/321654");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/tasks/321654", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/tasks/321654")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /tasks/{task_gid}

A specific, existing task can be deleted by making a DELETE request on the URL for that task. Deleted tasks go into the “trash” of the user making the delete request. Tasks can be recovered from the trash within a period of 30 days; afterward they are completely removed from the system.

Returns an empty data record.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully deleted the specified task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Duplicate a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/duplicate \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"New Task Name","include":["notes","assignee"]}}'
var data = JSON.stringify({
  "data": {
    "name": "New Task Name",
    "include": [
      "notes",
      "assignee"
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/duplicate");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/duplicate",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"New Task Name\",\"include\":[\"notes\",\"assignee\"]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"New Task Name\",\"include\":[\"notes\",\"assignee\"]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/duplicate", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/duplicate")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"New Task Name\",\"include\":[\"notes\",\"assignee\"]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/duplicate")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"New Task Name\",\"include\":[\"notes\",\"assignee\"]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/duplicate");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"New Task Name\",\"include\":[\"notes\",\"assignee\"]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/duplicate

Creates and returns a job that will asynchronously handle the duplication.

Body parameter

{
  "data": {
    "name": "New Task Name",
    "include": [
      "notes",
      "assignee"
    ]
  }
}

Parameters

Name In Type Required Description
body body object true Describes the duplicate's name and the fields that will be duplicated.
» data body object false none
»» name body string false The name of the new task.
»» include body string false The fields that will be duplicated to the new task.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
»» include notes
»» include assignee
»» include subtasks
»» include attachments
»» include tags
»» include followers
»» include projects
»» include dates
»» include dependencies
»» include parent

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "status": "in_progress",
    "new_project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "new_task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the job to handle duplication. JobObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a subtask

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654/subtasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654/subtasks");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/subtasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654/subtasks", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654/subtasks")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/subtasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/subtasks");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/subtasks

Returns a compact representation of all of the subtasks of a task.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified task's subtasks. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Create a subtask

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/subtasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Buy catnip","resource_subtype":"default_task","assignee":{"name":"Greg Sanchez"},"assignee_status":"upcoming","completed":false,"due_at":"2012-02-22T02:06:58.147Z","due_on":"2012-03-26","external":{"id":"my_id","data":"A blob of information"},"followers":[{"name":"Greg Sanchez"}],"html_notes":"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>","memberships":[{"project":{"name":"Stuff to buy","resource_type":"project"},"section":{"name":"Next Actions"}}],"notes":"Mittens really likes the stuff from Humboldt.","parent":{"name":"Bug Task"},"projects":[{"name":"Stuff to buy","resource_type":"project"}],"start_on":"2012-03-26","tags":[{"id":59746,"gid":"59746","name":"Grade A"}],"workspace":{"name":"Bug Task"}}}'
var data = JSON.stringify({
  "data": {
    "name": "Buy catnip",
    "resource_subtype": "default_task",
    "assignee": {
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "memberships": [
      {
        "project": {
          "name": "Stuff to buy",
          "resource_type": "project"
        },
        "section": {
          "name": "Next Actions"
        }
      }
    ],
    "notes": "Mittens really likes the stuff from Humboldt.",
    "parent": {
      "name": "Bug Task"
    },
    "projects": [
      {
        "name": "Stuff to buy",
        "resource_type": "project"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "name": "Bug Task"
    }
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/subtasks");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/subtasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/subtasks", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/subtasks")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/subtasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/subtasks");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Buy catnip\",\"resource_subtype\":\"default_task\",\"assignee\":{\"name\":\"Greg Sanchez\"},\"assignee_status\":\"upcoming\",\"completed\":false,\"due_at\":\"2012-02-22T02:06:58.147Z\",\"due_on\":\"2012-03-26\",\"external\":{\"id\":\"my_id\",\"data\":\"A blob of information\"},\"followers\":[{\"name\":\"Greg Sanchez\"}],\"html_notes\":\"<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>\",\"memberships\":[{\"project\":{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"},\"section\":{\"name\":\"Next Actions\"}}],\"notes\":\"Mittens really likes the stuff from Humboldt.\",\"parent\":{\"name\":\"Bug Task\"},\"projects\":[{\"name\":\"Stuff to buy\",\"resource_type\":\"project\"}],\"start_on\":\"2012-03-26\",\"tags\":[{\"id\":59746,\"gid\":\"59746\",\"name\":\"Grade A\"}],\"workspace\":{\"name\":\"Bug Task\"}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/subtasks

Creates a new subtask and adds it to the parent task. Returns the full record for the newly created subtask.

Body parameter

{
  "data": {
    "name": "Buy catnip",
    "resource_subtype": "default_task",
    "assignee": {
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "memberships": [
      {
        "project": {
          "name": "Stuff to buy",
          "resource_type": "project"
        },
        "section": {
          "name": "Next Actions"
        }
      }
    ],
    "notes": "Mittens really likes the stuff from Humboldt.",
    "parent": {
      "name": "Bug Task"
    },
    "projects": [
      {
        "name": "Stuff to buy",
        "resource_type": "project"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "name": "Bug Task"
    }
  }
}

Parameters

Name In Type Required Description
body body TaskObject true The new subtask to create.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Buy catnip",
    "created_at": "2012-02-22T02:06:58.147Z",
    "resource_subtype": "default_task",
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "completed_at": "2012-02-22T02:06:58.147Z",
    "custom_fields": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    ],
    "dependencies": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "dependents": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "hearted": true,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "liked": true,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "memberships": [
      {
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "section": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Next Actions"
        }
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "Mittens really likes the stuff from Humboldt.",
    "num_hearts": 5,
    "num_likes": 5,
    "num_subtasks": 3,
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "projects": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the specified subtask. TaskObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Change a task's parent

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/setParent \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"parent":987654,"insert_after":"null","insert_before":"124816"}}'
var data = JSON.stringify({
  "data": {
    "parent": 987654,
    "insert_after": "null",
    "insert_before": "124816"
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/setParent");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/setParent",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"parent\":987654,\"insert_after\":\"null\",\"insert_before\":\"124816\"}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"parent\":987654,\"insert_after\":\"null\",\"insert_before\":\"124816\"}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/setParent", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/setParent")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"parent\":987654,\"insert_after\":\"null\",\"insert_before\":\"124816\"}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/setParent")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"parent\":987654,\"insert_after\":\"null\",\"insert_before\":\"124816\"}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/setParent");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"parent\":987654,\"insert_after\":\"null\",\"insert_before\":\"124816\"}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/setParent

parent, or no parent task at all. Returns an empty data block. When using insert_before and insert_after, at most one of those two options can be specified, and they must already be subtasks of the parent.

Body parameter

{
  "data": {
    "parent": 987654,
    "insert_after": "null",
    "insert_before": "124816"
  }
}

Parameters

Name In Type Required Description
body body object true The new parent of the subtask.
» data body object false none
»» parent body integer true The new parent of the task, or null for no parent.
»» insert_after body integer false A subtask of the parent to insert the task after, or null to insert at the beginning of the list.
»» insert_before body integer false A subtask of the parent to insert the task before, or null to insert at the end of the list.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Buy catnip",
    "created_at": "2012-02-22T02:06:58.147Z",
    "resource_subtype": "default_task",
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "completed_at": "2012-02-22T02:06:58.147Z",
    "custom_fields": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    ],
    "dependencies": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "dependents": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "hearted": true,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "liked": true,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "memberships": [
      {
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "section": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Next Actions"
        }
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "Mittens really likes the stuff from Humboldt.",
    "num_hearts": 5,
    "num_likes": 5,
    "num_subtasks": 3,
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "projects": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully changed the parent of the specified subtask. TaskObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a task's dependencies

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654/dependencies \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654/dependencies");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/dependencies",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654/dependencies", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654/dependencies")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/dependencies")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/dependencies");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/dependencies

Returns the compact representations of all of the dependencies of a task.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified task's dependencies. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Set a task's dependencies

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/addDependencies \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"dependencies":[133713,184253]}}'
var data = JSON.stringify({
  "data": {
    "dependencies": [
      133713,
      184253
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/addDependencies");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/addDependencies",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"dependencies\":[133713,184253]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"dependencies\":[133713,184253]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/addDependencies", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/addDependencies")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"dependencies\":[133713,184253]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/addDependencies")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"dependencies\":[133713,184253]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/addDependencies");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"dependencies\":[133713,184253]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/addDependencies

Marks a set of tasks as dependencies of this task, if they are not already dependencies. A task can have at most 15 dependencies.

Body parameter

{
  "data": {
    "dependencies": [
      133713,
      184253
    ]
  }
}

Parameters

Name In Type Required Description
body body DependencyArray true The list of tasks to set as dependencies.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully set the specified dependencies on the task. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/removeDependencies \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"dependencies":[133713,184253]}}'
var data = JSON.stringify({
  "data": {
    "dependencies": [
      133713,
      184253
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/removeDependencies");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/removeDependencies",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"dependencies\":[133713,184253]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"dependencies\":[133713,184253]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/removeDependencies", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/removeDependencies")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"dependencies\":[133713,184253]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/removeDependencies")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"dependencies\":[133713,184253]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/removeDependencies");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"dependencies\":[133713,184253]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/removeDependencies

Unlinks a set of dependencies from this task.

Body parameter

{
  "data": {
    "dependencies": [
      133713,
      184253
    ]
  }
}
Name In Type Required Description
body body DependencyArray true The list of tasks to unlink as dependencies.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}
Status Meaning Description Schema
200 OK Successfully unlinked the dependencies from the specified task. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a task's dependents

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654/dependents \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654/dependents");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/dependents",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654/dependents", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654/dependents")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/dependents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/dependents");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/dependents

Returns the compact representations of all of the dependents of a task.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the specified dependents of the task. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Set a task's dependents

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/addDependents \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"dependents":[133713,184253]}}'
var data = JSON.stringify({
  "data": {
    "dependents": [
      133713,
      184253
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/addDependents");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/addDependents",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"dependents\":[133713,184253]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"dependents\":[133713,184253]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/addDependents", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/addDependents")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"dependents\":[133713,184253]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/addDependents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"dependents\":[133713,184253]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/addDependents");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"dependents\":[133713,184253]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/addDependents

Marks a set of tasks as dependents of this task, if they are not already dependents. A task can have at most 30 dependents.

Body parameter

{
  "data": {
    "dependents": [
      133713,
      184253
    ]
  }
}

Parameters

Name In Type Required Description
body body DependentArray true The list of tasks to add as dependents.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully set the specified dependents on the given task. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/removeDependents \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"dependents":[133713,184253]}}'
var data = JSON.stringify({
  "data": {
    "dependents": [
      133713,
      184253
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/removeDependents");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/removeDependents",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"dependents\":[133713,184253]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"dependents\":[133713,184253]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/removeDependents", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/removeDependents")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"dependents\":[133713,184253]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/removeDependents")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"dependents\":[133713,184253]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/removeDependents");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"dependents\":[133713,184253]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/removeDependents

Unlinks a set of dependents from this task.

Body parameter

{
  "data": {
    "dependents": [
      133713,
      184253
    ]
  }
}
Name In Type Required Description
body body DependentArray true The list of tasks to remove as dependents.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}
Status Meaning Description Schema
200 OK Successfully unlinked the specified tasks as dependents. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get projects a task is in

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654/projects \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654/projects");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/projects",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654/projects", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654/projects")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/projects")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/projects");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/projects

Returns a compact representation of all of the projects the task is in.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy",
      "created_at": "2012-02-22T02:06:58.147Z",
      "archived": false,
      "color": "light-green",
      "current_status": {
        "color": "green",
        "text": "Everything is great",
        "author": {
          "id": 12345,
          "name": "Greg Bizarro"
        }
      },
      "custom_fields": [],
      "custom_field_settings": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "is_important": false,
          "parent": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "custom_field": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "resource_subtype": "milestone",
            "type": "text",
            "enum_options": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              }
            ],
            "enum_value": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            },
            "enabled": true,
            "text_value": "Some Value",
            "description": "Development team priority",
            "precision": 2
          }
        }
      ],
      "due_date": "2012-03-26",
      "due_on": "2012-03-26",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "html_notes": "These are things we need to purchase.",
      "is_template": false,
      "layout": "list",
      "members": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "These are things we need to purchase.",
      "owner": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "public": false,
      "section_migration_status": "not_migrated",
      "start_on": "2012-03-26",
      "team": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the projects for the given task. ProjectArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a project to a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/addProject \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"project":13579,"insert_after":124816,"insert_before":432134,"section":987654}}'
var data = JSON.stringify({
  "data": {
    "project": 13579,
    "insert_after": 124816,
    "insert_before": 432134,
    "section": 987654
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/addProject");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/addProject",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"project\":13579,\"insert_after\":124816,\"insert_before\":432134,\"section\":987654}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"project\":13579,\"insert_after\":124816,\"insert_before\":432134,\"section\":987654}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/addProject", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/addProject")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"project\":13579,\"insert_after\":124816,\"insert_before\":432134,\"section\":987654}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/addProject")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"project\":13579,\"insert_after\":124816,\"insert_before\":432134,\"section\":987654}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/addProject");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"project\":13579,\"insert_after\":124816,\"insert_before\":432134,\"section\":987654}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/addProject

Adds the task to the specified project, in the optional location specified. If no location arguments are given, the task will be added to the end of the project.

addProject can also be used to reorder a task within a project or section that already contains it.

At most one of insert_before, insert_after, or section should be specified. Inserting into a section in an non-order-dependent way can be done by specifying section, otherwise, to insert within a section in a particular place, specify insert_before or insert_after and a task within the section to anchor the position of this task.

Returns an empty data block.

Body parameter

{
  "data": {
    "project": 13579,
    "insert_after": 124816,
    "insert_before": 432134,
    "section": 987654
  }
}

Parameters

Name In Type Required Description
body body object true The project to add the task to.
» data body object false none
»» project body integer true The project to add the task to.
»» insert_after body integer¦null false A task in the project to insert the task after, or null to insert at the beginning of the list.
»» insert_before body integer¦null false A task in the project to insert the task before, or null to insert at the end of the list.
»» section body integer¦null false A section in the project to insert the task into. The task will be inserted at the bottom of the section.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the specified project to the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a project a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/removeProject \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"project":13579}}'
var data = JSON.stringify({
  "data": {
    "project": 13579
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/removeProject");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/removeProject",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"project\":13579}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"project\":13579}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/removeProject", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/removeProject")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"project\":13579}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/removeProject")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"project\":13579}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/removeProject");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"project\":13579}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/removeProject

Removes the task from the specified project. The task will still exist in the system, but it will not be in the project anymore.

Returns an empty data block.

Body parameter

{
  "data": {
    "project": 13579
  }
}

Parameters

Name In Type Required Description
body body object true The project to remove the task from.
» data body object false none
»» project body integer true The project to remove the task from.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully removed the specified project from the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a task's tags

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/tasks/321654/tags \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/tasks/321654/tags");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/tags",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/tasks/321654/tags", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/tasks/321654/tags")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/tags")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/tags");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /tasks/{task_gid}/tags

Get a compact representation of all of the tags the task has.

Parameters

Name In Type Required Description
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "color": "light-green",
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the tags for the given task. TagArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a tag to a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/addTag \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"tag":13579}}'
var data = JSON.stringify({
  "data": {
    "tag": 13579
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/addTag");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/addTag",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"tag\":13579}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"tag\":13579}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/addTag", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/addTag")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"tag\":13579}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/addTag")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"tag\":13579}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/addTag");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"tag\":13579}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/addTag

Adds a tag to a task. Returns an empty data block.

Body parameter

{
  "data": {
    "tag": 13579
  }
}

Parameters

Name In Type Required Description
body body object true The tag to add to the task.
» data body object false none
»» tag body integer true The tag to add to the task.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the specified tag to the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a tag from a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/removeTag \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"tag":13579}}'
var data = JSON.stringify({
  "data": {
    "tag": 13579
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/removeTag");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/removeTag",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"tag\":13579}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"tag\":13579}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/removeTag", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/removeTag")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"tag\":13579}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/removeTag")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"tag\":13579}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/removeTag");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"tag\":13579}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/removeTag

Removes a tag from a task. Returns an empty data block.

Body parameter

{
  "data": {
    "tag": 13579
  }
}

Parameters

Name In Type Required Description
body body object true The tag to remove from the task.
» data body object false none
»» tag body integer true The tag to remove from the task.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully removed the specified tag from the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add followers to a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/addFollowers \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"followers":[13579,321654]}}'
var data = JSON.stringify({
  "data": {
    "followers": [
      13579,
      321654
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/addFollowers");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/addFollowers",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"followers\":[13579,321654]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"followers\":[13579,321654]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/addFollowers", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/addFollowers")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"followers\":[13579,321654]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/addFollowers")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"followers\":[13579,321654]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/addFollowers");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"followers\":[13579,321654]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/addFollowers

Adds a tag to a task. Returns an empty data block. Each task can be associated with zero or more followers in the system. Requests to add/remove followers, if successful, will return the complete updated task record, described above.

Body parameter

{
  "data": {
    "followers": [
      13579,
      321654
    ]
  }
}

Parameters

Name In Type Required Description
body body object true The tag to add to the task.
» data body object false none
»» followers body [integer] true The tag to add to the task.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully added the specified tag to the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove followers from a task

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/tasks/321654/removeFollowers \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"followers":[13579,321654]}}'
var data = JSON.stringify({
  "data": {
    "followers": [
      13579,
      321654
    ]
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/tasks/321654/removeFollowers");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/tasks/321654/removeFollowers",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"data\":{\"followers\":[13579,321654]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"followers\":[13579,321654]}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/tasks/321654/removeFollowers", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/tasks/321654/removeFollowers")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"followers\":[13579,321654]}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/tasks/321654/removeFollowers")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"followers\":[13579,321654]}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/tasks/321654/removeFollowers");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"followers\":[13579,321654]}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /tasks/{task_gid}/removeFollowers

Removes each of the specified followers from the task if they are following. Returns the complete, updated record for the affected task.

Body parameter

{
  "data": {
    "followers": [
      13579,
      321654
    ]
  }
}

Parameters

Name In Type Required Description
body body object true The tag to remove to the task.
» data body object false none
»» followers body [integer] true The tag to add to the task.
task_gid path string true The task to operate on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully removed the specified tag to the task. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Team

A team is used to group related projects and people together within an organization. Each project in an organization is associated with a team.

Get a team

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/teams/14916 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/teams/14916");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/teams/14916",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/teams/14916", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/teams/14916")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/teams/14916")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/teams/14916");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /teams/{team_gid}

Returns the full record for a single team.

Parameters

Name In Type Required Description
team_gid path integer true Globally unique identifier for the team.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "description": "All developers should be members of this team.",
    "html_description": "<body><em>All</em> developers should be members of this team.</body>",
    "organization": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successsfully retrieved the record for a single team. TeamObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get teams in an organization

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/organizations/1331/teams \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/organizations/1331/teams");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/organizations/1331/teams",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/organizations/1331/teams", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/organizations/1331/teams")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/organizations/1331/teams")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/organizations/1331/teams");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /organizations/{organization_gid}/teams

Returns the compact records for all teams in the organization visible to the authorized user.

Parameters

Name In Type Required Description
organization_gid path integer true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "description": "All developers should be members of this team.",
      "html_description": "<body><em>All</em> developers should be members of this team.</body>",
      "organization": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the team records for all teams in the organization or workspace accessible to the authenticated user. TeamArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a user's teams

Code samples

curl --request GET \
  --url 'https://app.asana.com/api/1.0/users/string/teams?organization_gid=1331' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/users/string/teams?organization_gid=1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/users/string/teams?organization_gid=1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/users/string/teams?organization_gid=1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/users/string/teams?organization_gid=1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/users/string/teams?organization_gid=1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/users/string/teams?organization_gid=1331");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /users/{user_gid}/teams

Returns the compact records for all teams to which the given user is assigned.

Parameters

Name In Type Required Description
user_gid path any true An identifier for the user. Can be one of an email address, the globally unique identifier for the user, or the keyword me to indicate the current user making the request.
organization_gid query integer true The workspace or organization to filter teams on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "description": "All developers should be members of this team.",
      "html_description": "<body><em>All</em> developers should be members of this team.</body>",
      "organization": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the team records for all teams in the organization or workspace to which the given user is assigned. TeamArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get users in a team

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/teams/0/users \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/teams/0/users");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/teams/0/users",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/teams/0/users", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/teams/0/users")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/teams/0/users")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/teams/0/users");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /teams/{team_gid}/users

Returns the compact records for all users that are members of the team.

Parameters

Name In Type Required Description
team_gid path integer true A globally unique identifier for the team.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the user records for all the members of the team, including guests and limited access users UserArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a user to a team

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/teams/0/addUser \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"user":14641}'
var data = JSON.stringify({
  "user": 14641
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/teams/0/addUser");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/teams/0/addUser",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"user\":14641}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"user\":14641}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/teams/0/addUser", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/teams/0/addUser")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"user\":14641}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/teams/0/addUser")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"user\":14641}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/teams/0/addUser");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"user\":14641}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /teams/{team_gid}/addUser

The user making this call must be a member of the team in order to add others. The user being added must exist in the same organization as the team.

Body parameter

{
  "user": 14641
}

Parameters

Name In Type Required Description
body body UserIdObject true The user to add to the team.
team_gid path integer true A globally unique identifier for the team.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns the full user record for the added user. UserArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a user from a team

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/teams/0/removeUser \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"user":14641}'
var data = JSON.stringify({
  "user": 14641
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/teams/0/removeUser");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/teams/0/removeUser",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"user\":14641}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"user\":14641}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/teams/0/removeUser", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/teams/0/removeUser")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"user\":14641}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/teams/0/removeUser")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"user\":14641}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/teams/0/removeUser");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"user\":14641}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /teams/{team_gid}/removeUser

The user making this call must be a member of the team in order to remove themselves or others.

Body parameter

{
  "user": 14641
}

Parameters

Name In Type Required Description
body body UserIdObject true The user to remove from the team.
team_gid path integer true A globally unique identifier for the team.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Returns an empty data record UserArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Users

A user object represents an account in Asana that can be given access to various workspaces, projects, and tasks.

Get a set of users

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/users \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/users");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/users",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/users", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/users")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/users")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/users");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /users

Returns the user records for all users in all workspaces and organizations accessible to the authenticated user. Accepts an optional workspace ID parameter. Results are sorted by user ID.

Parameters

Name In Type Required Description
workspace query integer false The workspace or organization ID to filter users on.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested user records. UserArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a user

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/users/string \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/users/string");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/users/string",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/users/string", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/users/string")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/users/string")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/users/string");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /users/{user_gid}

Returns the full user record for the single user with the provided ID. Results are sorted by user ID.

Parameters

Name In Type Required Description
user_gid path string true Globally unique identifier for the user.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  }
}

Responses

Status Meaning Description Schema
200 OK Returns the user specified. UserObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a user's favorites

Code samples

curl --request GET \
  --url 'https://app.asana.com/api/1.0/users/string/favorites?workspace=1234&resource_type=project' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/users/string/favorites?workspace=1234&resource_type=project");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/users/string/favorites?workspace=1234&resource_type=project",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/users/string/favorites?workspace=1234&resource_type=project", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/users/string/favorites?workspace=1234&resource_type=project")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/users/string/favorites?workspace=1234&resource_type=project")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/users/string/favorites?workspace=1234&resource_type=project");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /users/{user_gid}/favorites

Returns all of a user's favorites in the given workspace, of the given type. Results are given in order (The same order as Asana's sidebar).

Parameters

Name In Type Required Description
user_gid path string true Globally unique identifier for the user.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.
resource_type query string true The resource type of favorites to be returned.
workspace query string true The workspace in which to get favorites.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
resource_type portfolio
resource_type project
resource_type tag
resource_type task
resource_type user

Example responses

200 Response

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task"
}

Responses

Status Meaning Description Schema
200 OK Returns the specified user's favorites. AsanaObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get users in a workspace or organization

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces/12345/users \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/12345/users");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/users",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/12345/users", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/12345/users")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/users")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/users");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}/users

Returns the user records for all users in the specified workspace or organization. Results are sorted alphabetically by user names.

Parameters

Name In Type Required Description
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Return the users in the specified workspace or org. UserArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

User Task Lists

A user task list represents the tasks assigned to a particular user.

Get a user task list

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/user_task_list/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/user_task_list/12345");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/user_task_list/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/user_task_list/12345", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/user_task_list/12345")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/user_task_list/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/user_task_list/12345");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /user_task_list/{user_task_list_gid}

Returns the full record for a user task list.

Parameters

Name In Type Required Description
user_task_list_gid path string true Globally unique identifier for the user task list.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the user task list. UserTaskListObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a user's task list

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/users/string/user_task_list \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/users/string/user_task_list");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/users/string/user_task_list",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/users/string/user_task_list", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/users/string/user_task_list")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/users/string/user_task_list")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/users/string/user_task_list");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /users/{user_gid}/user_task_list

Returns the full record for a user's task list.

Parameters

Name In Type Required Description
user_gid path string true Globally unique identifier for the user.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the user's task list. UserTaskListObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get tasks in a user task list

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/user_task_lists/12345/tasks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/user_task_lists/12345/tasks");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/user_task_lists/12345/tasks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/user_task_lists/12345/tasks", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/user_task_lists/12345/tasks")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/user_task_lists/12345/tasks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/user_task_lists/12345/tasks");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /user_task_lists/{user_task_list_gid}/tasks

Returns the compact list of tasks in a user’s My Tasks list. The returned tasks will be in order within each assignee status group of Inbox, Today, and Upcoming. Note: tasks in Later have a different ordering in the Asana web app than the other assignee status groups; this endpoint will still return them in list order in Later (differently than they show up in Asana, but the same order as in Asana’s mobile apps). Note: Access control is enforced for this endpoint as with all Asana API endpoints, meaning a user’s private tasks will be filtered out if the API-authenticated user does not have access to them. Note: Both complete and incomplete tasks are returned by default unless they are filtered out (for example, setting completed_since=now will return only incomplete tasks, which is the default view for “My Tasks” in Asana.)

Parameters

Name In Type Required Description
completed_since query string false Only return tasks that are either incomplete or that have been completed since this time. Accepts a date-time string or the keyword now.
user_task_list_gid path string true Globally unique identifier for the user task list.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

completed_since: Only return tasks that are either incomplete or that have been completed since this time. Accepts a date-time string or the keyword now.

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the user task list's tasks. TaskArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Webhooks

Webhooks allow an application to be notified of changes in Asana.

Get a set of webhooks

Code samples

curl --request GET \
  --url 'https://app.asana.com/api/1.0/webhooks?workspace=1331' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/webhooks?workspace=1331");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/webhooks?workspace=1331",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/webhooks?workspace=1331", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/webhooks?workspace=1331")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/webhooks?workspace=1331")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/webhooks?workspace=1331");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /webhooks

Get the compact representation of all webhooks your app has registered for the authenticated user in the given workspace.

Parameters

Name In Type Required Description
workspace query integer true The workspace to query for webhooks in.
resource query integer false Only return webhooks for the given resource.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "created_at": "2012-02-22T02:06:58.147Z",
      "active": false,
      "last_failure_at": "2012-02-22T02:06:58.147Z",
      "last_failure_content": "500 Server Error\\n\\nCould not complete the request",
      "last_success_at": "2012-02-22T02:06:58.147Z",
      "resource": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "target": "https://example.com/receive-webhook/7654"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested webhooks. WebhookArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Establish a webhook on a resource

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/webhooks \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"resource":12345,"target":"https://example.com/receive-webhook/7654"}'
var data = JSON.stringify({
  "resource": 12345,
  "target": "https://example.com/receive-webhook/7654"
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/webhooks");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/webhooks",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"resource\":12345,\"target\":\"https://example.com/receive-webhook/7654\"}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"resource\":12345,\"target\":\"https://example.com/receive-webhook/7654\"}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/webhooks", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/webhooks")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"resource\":12345,\"target\":\"https://example.com/receive-webhook/7654\"}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/webhooks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"resource\":12345,\"target\":\"https://example.com/receive-webhook/7654\"}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/webhooks");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"resource\":12345,\"target\":\"https://example.com/receive-webhook/7654\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /webhooks

Establishing a webhook is a two-part process. First, a simple HTTP POST similar to any other resource creation. Since you could have multiple webhooks we recommend specifying a unique local id for each target.

Next comes the confirmation handshake. When a webhook is created, we will send a test POST to the target with an X-Hook-Secret header as described in the Resthooks Security documentation. The target must respond with a 200 OK and a matching X-Hook-Secret header to confirm that this webhook subscription is indeed expected.

If you do not acknowledge the webhook’s confirmation handshake it will fail to setup, and you will receive an error in response to your attempt to create it. This means you need to be able to receive and complete the webhook while the POST request is in-flight.

# Request
curl -H "Authorization: Bearer <personal_access_token>" \
-X POST https://app.asana.com/api/1.0/webhooks \
-d "resource=8675309" \
-d "target=https://example.com/receive-webhook/7654"
# Handshake sent to https://example.com/
POST /receive-webhook/7654
X-Hook-Secret: b537207f20cbfa02357cf448134da559e8bd39d61597dcd5631b8012eae53e81
# Handshake response sent by example.com
HTTP/1.1 200
X-Hook-Secret: b537207f20cbfa02357cf448134da559e8bd39d61597dcd5631b8012eae53e81
# Response
HTTP/1.1 201
{
  "data": {
    "id": 43214,
    "resource": {
      "id": 8675309,
      "name": "Bugs"
    },
    "target": "https://example.com/receive-webhook/7654",
    "active": false,
    "last_success_at": null,
    "last_failure_at": null,
    "last_failure_content": null
  }
}

Body parameter

{
  "resource": 12345,
  "target": "https://example.com/receive-webhook/7654"
}

Parameters

Name In Type Required Description
body body object true The webhook workspace and target.
» resource body integer true A resource ID to subscribe to. The resource can be a task or project.
» target body string(uri) true The URL to receive the HTTP POST.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

201 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "active": false,
    "last_failure_at": "2012-02-22T02:06:58.147Z",
    "last_failure_content": "500 Server Error\\n\\nCould not complete the request",
    "last_success_at": "2012-02-22T02:06:58.147Z",
    "resource": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "target": "https://example.com/receive-webhook/7654"
  }
}

Responses

Status Meaning Description Schema
201 Created Successfully created the requested webhook. WebhookObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a webhook

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/webhooks/95784 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/webhooks/95784");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/webhooks/95784",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/webhooks/95784", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/webhooks/95784")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/webhooks/95784")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/webhooks/95784");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /webhooks/{webhook_gid}

Returns the full record for the given webhook.

Parameters

Name In Type Required Description
webhook_gid path integer true The webhook to affect with the current operation.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "active": false,
    "last_failure_at": "2012-02-22T02:06:58.147Z",
    "last_failure_content": "500 Server Error\\n\\nCould not complete the request",
    "last_success_at": "2012-02-22T02:06:58.147Z",
    "resource": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "target": "https://example.com/receive-webhook/7654"
  }
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested webhook. WebhookObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a webhook

Code samples

curl --request DELETE \
  --url https://app.asana.com/api/1.0/webhooks/95784 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://app.asana.com/api/1.0/webhooks/95784");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/webhooks/95784",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("DELETE", "/api/1.0/webhooks/95784", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.delete("https://app.asana.com/api/1.0/webhooks/95784")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/webhooks/95784")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/webhooks/95784");
var request = new RestRequest(Method.DELETE);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

DELETE /webhooks/{webhook_gid}

This method permanently removes a webhook. Note that it may be possible to receive a request that was already in flight after deleting the webhook, but no further requests will be issued.

Parameters

Name In Type Required Description
webhook_gid path integer true The webhook to affect with the current operation.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {}
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved the requested webhook. EmptyObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Workspaces

A workspace is the highest-level organizational unit in Asana. An organization is a special kind of workspace that represents a company.

Retrieve objects via typeahead

Code samples

curl --request GET \
  --url 'https://app.asana.com/api/1.0/workspaces/12345/typeahead?resource_type=user' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/12345/typeahead?resource_type=user");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/typeahead?resource_type=user",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/12345/typeahead?resource_type=user", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/12345/typeahead?resource_type=user")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/typeahead?resource_type=user")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/typeahead?resource_type=user");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}/typeahead

Retrieves objects in the workspace based via an auto-completion/typeahead search algorithm. This feature is meant to provide results quickly, so do not rely on this API to provide extremely accurate search results. The result set is limited to a single page of results with a maximum size, so you won’t be able to fetch large numbers of results.

The typeahead search API provides search for objects from a single workspace. This endpoint should be used to query for objects when creating an auto-completion/typeahead search feature. This API is meant to provide results quickly and should not be relied upon for accurate or exhaustive search results. The results sets are limited in size and cannot be paginated.

Queries return a compact representation of each object which is typically the id and name fields. Interested in a specific set of fields or all of the fields?! Of course you are. Use field selectors to manipulate what data is included in a response.

Parameters

Name In Type Required Description
workspace_gid path string true Globally unique identifier for the workspace or organization.
resource_type query string true The type of values the typeahead should return. You can choose from one of the following: custom_field, project, tag, task, and user. Note that unlike in the names of endpoints, the types listed here are in singular form (e.g. task). Using multiple types is not yet supported.
type query string false Deprecated: new integrations should prefer the resource_type field.
query query string false The string that will be used to search for relevant objects. If an empty string is passed in, the API will currently return an empty result set.
count query integer false The number of results to return. The default is 20 if this parameter is omitted, with a minimum of 1 and a maximum of 100. If there are fewer results found than requested, all will be returned.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Enumerated Values

Parameter Value
resource_type custom_field
resource_type portfolio
resource_type project
resource_type tag
resource_type task
resource_type user
type custom_field
type portfolio
type project
type tag
type task
type user

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Successfully retrieved objects via a typeahead search algorithm. AsanaObjectArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a set of workspaces

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces

Returns the compact records for all workspaces visible to the authorized user.

Parameters

Name In Type Required Description
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "email_domains": [
        "asana.com"
      ],
      "is_organization": false
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Return all workspaces visible to the authorized user. WorkspaceArray
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Get a workspace

Code samples

curl --request GET \
  --url https://app.asana.com/api/1.0/workspaces/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}'
var data = null;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://app.asana.com/api/1.0/workspaces/12345");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

headers = {
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("GET", "/api/1.0/workspaces/12345", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.get("https://app.asana.com/api/1.0/workspaces/12345")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
IRestResponse response = client.Execute(request);

GET /workspaces/{workspace_gid}

Returns the full workspace record for a single workspace.

Parameters

Name In Type Required Description
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "email_domains": [
      "asana.com"
    ],
    "is_organization": false
  }
}

Responses

Status Meaning Description Schema
200 OK Return the full workspace record. WorkspaceObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Update a workspace

Code samples

curl --request PUT \
  --url https://app.asana.com/api/1.0/workspaces/12345 \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"data":{"name":"Bug Task","email_domains":["asana.com"],"is_organization":false}}'
var data = JSON.stringify({
  "data": {
    "name": "Bug Task",
    "email_domains": [
      "asana.com"
    ],
    "is_organization": false
  }
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("PUT", "https://app.asana.com/api/1.0/workspaces/12345");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"data\":{\"name\":\"Bug Task\",\"email_domains\":[\"asana.com\"],\"is_organization\":false}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"data\":{\"name\":\"Bug Task\",\"email_domains\":[\"asana.com\"],\"is_organization\":false}}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("PUT", "/api/1.0/workspaces/12345", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.put("https://app.asana.com/api/1.0/workspaces/12345")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"data\":{\"name\":\"Bug Task\",\"email_domains\":[\"asana.com\"],\"is_organization\":false}}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"data\":{\"name\":\"Bug Task\",\"email_domains\":[\"asana.com\"],\"is_organization\":false}}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345");
var request = new RestRequest(Method.PUT);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"data\":{\"name\":\"Bug Task\",\"email_domains\":[\"asana.com\"],\"is_organization\":false}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

PUT /workspaces/{workspace_gid}

A specific, existing workspace can be updated by making a PUT request on the URL for that workspace. Only the fields provided in the data block will be updated; any unspecified fields will remain unchanged. Currently the only field that can be modified for a workspace is its name. Returns the complete, updated workspace record.

Body parameter

{
  "data": {
    "name": "Bug Task",
    "email_domains": [
      "asana.com"
    ],
    "is_organization": false
  }
}

Parameters

Name In Type Required Description
body body WorkspaceObject true The workspace object with all updated properties.
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "email_domains": [
      "asana.com"
    ],
    "is_organization": false
  }
}

Responses

Status Meaning Description Schema
200 OK Update for the workspace was successful. WorkspaceObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Add a user to a workspace or organization

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/workspaces/12345/addUser \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"user":14641}'
var data = JSON.stringify({
  "user": 14641
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/workspaces/12345/addUser");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/addUser",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"user\":14641}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"user\":14641}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/workspaces/12345/addUser", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/workspaces/12345/addUser")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"user\":14641}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/addUser")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"user\":14641}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/addUser");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"user\":14641}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /workspaces/{workspace_gid}/addUser

Add a user to a workspace or organization. The user can be referenced by their globally unique user ID or their email address. Returns the full user record for the invited user.

Body parameter

{
  "user": 14641
}

Parameters

Name In Type Required Description
body body UserIdObject true The user to add to the workspace.
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  }
}

Responses

Status Meaning Description Schema
200 OK The user was added successfully to the workspace or organization. UserObject
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Remove a user from a workspace or organization

Code samples

curl --request POST \
  --url https://app.asana.com/api/1.0/workspaces/12345/removeUser \
  --header 'accept: application/json' \
  --header 'authorization: Bearer {access-token}' \
  --header 'content-type: application/json' \
  --data '{"user":14641}'
var data = JSON.stringify({
  "user": 14641
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://app.asana.com/api/1.0/workspaces/12345/removeUser");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("authorization", "Bearer {access-token}");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://app.asana.com/api/1.0/workspaces/12345/removeUser",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"user\":14641}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "authorization: Bearer {access-token}",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("app.asana.com")

payload = "{\"user\":14641}"

headers = {
    'content-type': "application/json",
    'accept': "application/json",
    'authorization': "Bearer {access-token}"
    }

conn.request("POST", "/api/1.0/workspaces/12345/removeUser", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
HttpResponse<String> response = Unirest.post("https://app.asana.com/api/1.0/workspaces/12345/removeUser")
  .header("content-type", "application/json")
  .header("accept", "application/json")
  .header("authorization", "Bearer {access-token}")
  .body("{\"user\":14641}")
  .asString();
require 'uri'
require 'net/http'

url = URI("https://app.asana.com/api/1.0/workspaces/12345/removeUser")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["accept"] = 'application/json'
request["authorization"] = 'Bearer {access-token}'
request.body = "{\"user\":14641}"

response = http.request(request)
puts response.read_body
var client = new RestClient("https://app.asana.com/api/1.0/workspaces/12345/removeUser");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer {access-token}");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"user\":14641}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

POST /workspaces/{workspace_gid}/removeUser

Remove a user from a workspace or organization. The user making this call must be an admin in the workspace. The user can be referenced by their globally unique user ID or their email address. Returns an empty data record.

Body parameter

{
  "user": 14641
}

Parameters

Name In Type Required Description
body body UserIdObject true The user to remove from the workspace.
workspace_gid path string true Globally unique identifier for the workspace or organization.
opt_pretty query boolean false Provides “pretty” output.
opt_fields query array[string] false Defines fields to return.
opt_expand query array[string] false Expand fields returned.
limit query integer false Results per page.
offset query string false Offset token.

Detailed descriptions

opt_pretty: Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging.

opt_fields: Defines fields to return. Some requests return compact representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options.

opt_expand: Expand fields returned. Query results and sub-objects are returned in compact form by default. This option can be used to expand query results or sub-objects to return more detailed information. Be sure you really need the information in the expanded form, as executing a query with many results in expanded form can be costly and return you a lot of data to consume. If the fields option is also used, it will take precedence over the expand option and prevent expansion.

limit: Results per page. The number of objects to return per page. The value must be between 1 and 100.

offset: Offset token. An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results. 'Note: You can only pass in an offset that was returned to you via a previously paginated request.'

Example responses

200 Response

{}

Responses

Status Meaning Description Schema
200 OK The user was removed successfully to the workspace or organization. Inline
400 Bad Request This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again. Error
401 Unauthorized A valid authentication token was not provided with the request, so the API could not associate a user with the request. Error
403 Forbidden The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to. Error
404 Not Found Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist. Error
5XX Unknown There was a problem on Asana’s end. Error
default Default Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information. In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error. Error

Response Schema

Schemas

AsanaObject

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task"
}

A generic Asana Object, containing a globally unique identifier.

Properties

Name Type Required Restrictions Description
id integer(int64) false read-only Globally unique ID of the attachment, as an integer. Note: This field is under active migration to the gid field—please see our blog post for more information.
gid string false read-only Globally unique ID of the object, as a string.
resource_type string false read-only The base type of this resource.

AsanaNamedObject

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous object false none none
» name string false none The name of the object.

AsanaObjectArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  ]
}

A generic list of objects, such as those returned by the typeahead search endpoint.

Properties

Name Type Required Restrictions Description
data [AsanaNamedObject] false none none

AsanaSubtype

{
  "resource_subtype": "milestone"
}

Properties

Name Type Required Restrictions Description
resource_subtype string false none The subtype of this resource. Different subtypes retain many of the same fields and behavior, but may render differently in Asana or represent resources with different semantic meaning.

AsanaCreatedAt

{
  "created_at": "2012-02-22T02:06:58.147Z"
}

Properties

Name Type Required Restrictions Description
created_at string(date-time) false read-only The time at which this resource was created.

AsanaCreatedByAndAt

{
  "created_at": "2012-02-22T02:06:58.147Z",
  "created_by": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» created_by any false none none

allOf

Name Type Required Restrictions Description
»» anonymous User false none none

and

Name Type Required Restrictions Description
»» anonymous object¦null false read-only The user who created this resource.

Attachment

{
  "name": "Screenshot.png",
  "created_at": "2012-02-22T02:06:58.147Z",
  "download_url": "https://www.dropbox.com/s/123/Screenshot.png?dl=1",
  "host": "dropbox",
  "parent": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "view_url": "https://www.dropbox.com/s/123/Screenshot.png"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AttachmentCompact false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous object false none An attachment object represents any file attached to a task in Asana, whether it’s an uploaded file or one associated via a third-party service such as Dropbox or Google Drive.
» download_url string(uri)¦null false read-only The URL containing the content of the attachment.
Note: May be null if the attachment is hosted by Box. If present, this URL may only be valid for 1 hour from the time of retrieval. You should avoid persisting this URL somewhere and just refresh it on demand to ensure you do not keep stale URLs.
» host string false read-only The service hosting the attachment. Valid values are asana, dropbox, gdrive and box.
» parent any false none none

allOf

Name Type Required Restrictions Description
»» anonymous TaskCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false read-only The task this attachment is attached to.

continued

Name Type Required Restrictions Description
» view_url string(uri)¦null false read-only The URL where the attachment can be viewed, which may be friendlier to users in a browser than just directing them to a raw file. May be null if no view URL exists for the service.

AttachmentCompact

{
  "name": "Screenshot.png"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous #/Components/schemas/AsanaObject false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» name string false read-only The name of the file.

AttachmentObject

{
  "data": {
    "name": "Screenshot.png",
    "created_at": "2012-02-22T02:06:58.147Z",
    "download_url": "https://www.dropbox.com/s/123/Screenshot.png?dl=1",
    "host": "dropbox",
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "view_url": "https://www.dropbox.com/s/123/Screenshot.png"
  }
}

Properties

Name Type Required Restrictions Description
data Attachment false none none

AttachmentArray

{
  "data": [
    {
      "name": "Screenshot.png"
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [AttachmentCompact] false none none

BatchRequest

{
  "relative_path": "/tasks/123",
  "method": "get",
  "data": {
    "assignee": "me",
    "workspace": 1337
  },
  "options": {
    "limit": 3,
    "fields": [
      "name",
      "notes",
      "completed"
    ]
  }
}

A request object for use in a batch request.

Properties

Name Type Required Restrictions Description
relative_path string true none The path of the desired endpoint relative to the API’s base URL. Query parameters are not accepted here; put them in data instead.
method string true none The HTTP method you wish to emulate for the action.
data object false none For GET requests, this should be a map of query parameters you would have normally passed in the URL. Options and pagination are not accepted here; put them in options instead. For POST, PATCH, and PUT methods, this should be the content you would have normally put in the data field of the body.
options object false none Pagination (limit and offset) and output options (fields or expand) for the action. “Pretty” JSON output is not an available option on individual actions; if you want pretty output, specify that option on the parent request.
» limit integer false none Pagination limit for the request.
» offset integer false none Pagination offset for the request.
» fields [string] false none The fields to retrieve in the request.
» expand string false none The expansion path for the request.

Enumerated Values

Property Value
method get
method post
method put
method delete
method patch
method head

BatchResponse

{
  "status_code": 200,
  "headers": {
    "location": "/tasks/1234"
  },
  "body": {
    "data": {
      "id": 1967,
      "completed": false,
      "name": "Hello, world!",
      "notes": "How are you today?"
    }
  }
}

A response object returned from a batch request.

Properties

Name Type Required Restrictions Description
status_code integer false none The HTTP status code that the invoked endpoint returned.
headers object false none A map of HTTP headers specific to this result. This is primarily used for returning a Location header to accompany a 201 Created result. The parent HTTP response will contain all common headers.
body object false none The JSON body that the invoked endpoint returned.

CustomField

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task",
  "resource_subtype": "milestone",
  "type": "text",
  "enum_options": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    }
  ],
  "enum_value": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Low",
    "enabled": true,
    "color": "blue"
  },
  "enabled": true,
  "text_value": "Some Value",
  "description": "Development team priority",
  "precision": 2
}

Properties

allOf

Name Type Required Restrictions Description
anonymous CustomFieldCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none Custom Fields store the metadata that is used in order to
add user-specified information to tasks in Asana. Be sure
to reference the [Custom Fields]
(https://asana.com/developers/documentation/getting-started/custom-fields)
developer documentation for more information about how custom fields
relate to various resources in Asana.

Users in Asana can [lock custom fields]
(https://asana.com/guide/help/premium/custom-fields#gl-lock-fields),
which will make them read-only when accessed by other users.
Attempting to edit a locked custom field will return HTTP error code
403 Forbidden.
» description string false none Opt In. The description of the custom field.
» enum_options [EnumOption] false none Conditional. Only relevant for custom fields of type enum. This array specifies the possible values which an enum custom field can adopt. To modify the enum options, refer to working with enum options.
» precision integer false none Only relevant for custom fields of type ‘Number’. This field dictates the number of places after the decimal to round to, i.e. 0 is integer values, 1 rounds to the nearest tenth, and so on. Must be between 0 and 6, inclusive.

CustomFieldCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task",
  "resource_subtype": "milestone",
  "type": "text",
  "enum_options": [],
  "enum_value": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Low",
    "enabled": true,
    "color": "blue"
  },
  "enabled": true,
  "text_value": "Some Value"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
anonymous AsanaSubtype false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» type string false none Deprecated: new integrations should prefer the resource_subtype field. The type of the custom field. Must be one of the given values.
» enum_options [EnumOptionCompact] false none Conditional. Only relevant for custom fields of type enum. This array specifies the possible values which an enum custom field can adopt. To modify the enum options, refer to working with enum options.
» enum_value any false none none

allOf

Name Type Required Restrictions Description
»» anonymous EnumOption false none none

and

Name Type Required Restrictions Description
»» anonymous object false none Conditional. Only relevant for custom fields of type enum. This object is the chosen value of an enum custom field.

continued

Name Type Required Restrictions Description
» enabled boolean false none Conditional. Determines if the custom field is enabled or not.
» text_value string false none Conditional. This string is the value of a text custom field.

Enumerated Values

Property Value
type text
type enum
type number

CustomFieldObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
}

Properties

Name Type Required Restrictions Description
data CustomField false none none

CustomFieldArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [CustomFieldCompact] false none none

CustomFieldSettings

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "project": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy"
  },
  "is_important": false,
  "parent": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy"
  },
  "custom_field": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      }
    ],
    "enum_value": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value",
    "description": "Development team priority",
    "precision": 2
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous CustomFieldSettingsCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none Custom fields are attached to a particular project with the Custom Field Settings resource. This resource both represents the many-to-many join of the Custom Field and Project as well as stores information that is relevant to that particular pairing; for instance, the is_important property determines some possible application-specific handling of that custom field.
» project any false none none

allOf

Name Type Required Restrictions Description
»» anonymous ProjectCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false read-only Deprecated: new integrations should prefer the parent field. The id of the project that this custom field settings refers to.

continued

Name Type Required Restrictions Description
» is_important boolean false read-only is_important is used in the Asana web application to determine if this custom field is displayed in the task list (left pane) of a project. A project can have a maximum of 5 custom field settings marked as is_important.
» parent any false none none

allOf

Name Type Required Restrictions Description
»» anonymous ProjectCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false read-only The parent to which the custom field is applied. This can be a project or portfolio and indicates that the tasks or projects that the parent contains may be given custom field values for this custom field.

continued

Name Type Required Restrictions Description
» custom_field any false none none

allOf

Name Type Required Restrictions Description
»» anonymous CustomField false none none

and

Name Type Required Restrictions Description
»» anonymous object false none The custom field that is applied to the parent. readOnly: true

CustomFieldSettingsCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task"
}

Properties

None

CustomFieldSettingsArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "is_important": false,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [CustomFieldSettings] false none none

DependencyArray

{
  "data": {
    "dependencies": [
      133713,
      184253
    ]
  }
}

A set of task dependencies.

Properties

Name Type Required Restrictions Description
data object false none none
» dependencies [integer] false none An array of task IDs that a task should depend on.

DependentArray

{
  "data": {
    "dependents": [
      133713,
      184253
    ]
  }
}

A set of dependent tasks.

Properties

Name Type Required Restrictions Description
data object false none none
» dependents [integer] false none An array of task IDs that are dependents of the given task.

EmptyObject

{
  "data": {}
}

An empty object.

Properties

Name Type Required Restrictions Description
data object false none none

EnumOption

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Low",
  "enabled": true,
  "color": "blue"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous object false none Enum options are the possible values which an enum custom field can
adopt. An enum custom field must contain at least 1 enum option but no
more than 50.

You can add enum options to a custom field by using the POST<br>/custom_fields/custom_field_gid/enum_options endpoint.

It is not possible to remove or delete an enum option. Instead, enum
options can be disabled by updating the enabled field to false with the
PUT /enum_options/enum_option_gid endpoint. Other attributes can be
updated similarly.

On creation of an enum option, enabled is always set to true, meaning
the enum option is a selectable value for the custom field. Setting
enabled=false is equivalent to “trashing” the enum option in the Asana
web app within the “Edit Fields” dialog. The enum option will no longer
be selectable but, if the enum option value was previously set within a
task, the task will retain the value.

Enum options are an ordered list and by default new enum options are
inserted at the end. Ordering in relation to existing enum options can be
specified on creation by using insert_before or insert_after to
reference an existing enum option. Only one of insert_before and
insert_after can be provided when creating a new enum option.

An enum options list can be reordered with the POST<br>/custom_fields/custom_field_gid/enum_options/insert endpoint.
» name string false none The name of the enum option.
» enabled boolean false none The color of the enum option. Defaults to ‘none’.
» color string false none Whether or not the enum option is a selectable value for the custom field.

Error

{
  "errors": [
    {
      "message": "project: Missing input",
      "help": "For more information on API status codes and how to handle them, read the docs on errors: https://asana.com/developers/documentation/getting-started/errors'",
      "phrase": "6 sad squid snuggle softly"
    }
  ]
}

Sadly, sometimes requests to the API are not successful. Failures can occur for a wide range of reasons. In all cases, the API should return an HTTP Status Code that indicates the nature of the failure, with a response body in JSON format containing additional information.

In the event of a server error the response body will contain an error phrase. These phrases are automatically generated using the node-asana-phrase library and can be used by Asana support to quickly look up the incident that caused the server error.

Properties

Name Type Required Restrictions Description
errors [object] false none none
» message string false read-only Message providing more detail about the error that occurred, if available.
» help string false read-only Additional information directing developers to resources on how to address and fix the problem, if available.
» phrase string false read-only 500 errors only. A unique error phrase which can be used when contacting developer support to help identify the exact occurrence of the problem in Asana’s logs.

Event

{
  "user": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "resource": {
    "id": 12345,
    "name": "Bug Task"
  },
  "type": "task",
  "action": "changed",
  "parent": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "created_at": "2012-02-22T02:06:58.147Z"
}

An event is an object representing a change to a resource that was observed by an event subscription.

In general, requesting events on a resource is faster and subject to higher rate limits than requesting the resource itself. Additionally, change events bubble up - listening to events on a project would include when stories are added to tasks in the project, even on subtasks.

Establish an initial sync token by making a request with no sync token. The response will be a 412 error - the same as if the sync token had expired.

Subsequent requests should always provide the sync token from the immediately preceding call.

Sync tokens may not be valid if you attempt to go ‘backward’ in the history by requesting previous tokens, though re-requesting the current sync token is generally safe, and will always return the same results.

When you receive a 412 Precondition Failed error, it means that the sync token is either invalid or expired. If you are attempting to keep a set of data in sync, this signals you may need to re-crawl the data.

Sync tokens always expire after 24 hours, but may expire sooner, depending on load on the service.

Properties

Name Type Required Restrictions Description
user any false none none

allOf

Name Type Required Restrictions Description
» anonymous UserCompact false none none

and

Name Type Required Restrictions Description
» anonymous object¦null false read-only The user who triggered the event.

Note: The event may be triggered by a different user than the
subscriber. For example, if user A subscribes to a task and user B
modified it, the event’s user will be user B. Note: Some events are
generated by the system, and will have null as the user. API
consumers should make sure to handle this case.

continued

Name Type Required Restrictions Description
resource object false read-only The resource the event occurred on.

Note: The resource that triggered the event may be different from
the one that the events were requested for. For example, a
subscription to a project will contain events for tasks contained
within the project.
» id integer false none none
» name string false none none
type string false read-only Deprecated: Refer to the resource_type of the resource.
The type of the resource that generated the event.

Note: Currently, only tasks, projects and stories generate
events.
action string false read-only The type of action taken that triggered the event.
parent any false none none

allOf

Name Type Required Restrictions Description
» anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
» anonymous object¦null false read-only For added/removed events, the parent that resource was added to or removed from. The parent will be null for other event types.

continued

Name Type Required Restrictions Description
created_at string(date-time) false read-only The timestamp when the event occurred.

EventArray

{
  "data": [
    {
      "user": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "resource": {
        "id": 12345,
        "name": "Bug Task"
      },
      "type": "task",
      "action": "changed",
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "created_at": "2012-02-22T02:06:58.147Z"
    }
  ],
  "sync": "de4774f6915eae04714ca93bb2f5ee81"
}

The full record for all events that have occurred since the sync token was created.

Properties

Name Type Required Restrictions Description
data [Event] false none [An event is an object representing a change to a resource that was
observed by an event subscription.

In general, requesting events on a resource is faster and subject to
higher rate limits than requesting the resource itself. Additionally,
change events bubble up - listening to events on a project would include
when stories are added to tasks in the project, even on subtasks.

Establish an initial sync token by making a request with no sync token.
The response will be a 412 error - the same as if the sync token had
expired.

Subsequent requests should always provide the sync token from the
immediately preceding call.

Sync tokens may not be valid if you attempt to go ‘backward’ in the
history by requesting previous tokens, though re-requesting the current
sync token is generally safe, and will always return the same results.

When you receive a 412 Precondition Failed error, it means that the
sync token is either invalid or expired. If you are attempting to keep a
set of data in sync, this signals you may need to re-crawl the data.

Sync tokens always expire after 24 hours, but may expire sooner,
depending on load on the service.]
sync string false none A sync token to be used with the next call to the events endpoint.

Job

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "resource_subtype": "milestone",
  "status": "in_progress",
  "new_project": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy"
  },
  "new_task": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous AsanaSubtype false none none

and

Name Type Required Restrictions Description
anonymous object false none A job is an object representing a process that handles asynchronous work.
» status string false read-only none
» new_project ProjectCompact false none none
» new_task TaskCompact false none none

Enumerated Values

Property Value
status in_progress
status completed

JobObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "status": "in_progress",
    "new_project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "new_task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data Job false none none

OrganizationExport

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "created_at": "2012-02-22T02:06:58.147Z",
  "download_url": "https://asana-export.s3.amazonaws.com/export-4632784536274-20170127-43246.json.gz?AWSAccessKeyId=xxxxxxxx",
  "state": "started",
  "organization": {
    "id": 14916,
    "gid": "14916",
    "name": "My Workspace"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous object false none An organization_export object represents a request to export the
complete data of an Organization in JSON format.

To export an Organization using this API:

* Create an organization_export
request
and store the id that is returned.
* Request the organization_export every few minutes, until the state
field contains ‘finished’.
* Download the file located at the URL in the download_url field.
* Exports can take a long time, from several minutes to a few hours for
large Organizations.

Note: These endpoints are only available to Service
Accounts
of an
Enterprise Organization.
» download_url string(uri)¦null false read-only Download this URL to retreive the full export of the organization
in JSON format. It will be compressed in a gzip (.gz) container.

Note: May be null if the export is still in progress or
failed. If present, this URL may only be valid for 1 hour from
the time of retrieval. You should avoid persisting this URL
somewhere and rather refresh on demand to ensure you do not keep
stale URLs.
» state string false read-only The current state of the export.
» organization object false none Create-only: The Organization that is being exported. This can only be specified at create time.
»» id integer false none none
»» gid string false none none
»» name string false none none

Enumerated Values

Property Value
state pending
state started
state finished
state error

OrganizationExportObjectResponse

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "download_url": "https://asana-export.s3.amazonaws.com/export-4632784536274-20170127-43246.json.gz?AWSAccessKeyId=xxxxxxxx",
    "state": "started",
    "organization": {
      "id": 14916,
      "gid": "14916",
      "name": "My Workspace"
    }
  }
}

Properties

Name Type Required Restrictions Description
data OrganizationExport false none none

Portfolio

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "portfolio",
  "name": "Bug Task",
  "created_at": "2012-02-22T02:06:58.147Z",
  "created_by": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  },
  "color": "light-green",
  "custom_field_settings": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "is_important": false,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    }
  ],
  "owner": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "workspace": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "members": {
    "data": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ]
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous PortfolioCompact false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedByAndAt false none none

and

Name Type Required Restrictions Description
anonymous object false none A portfolio gives a high-level overview of the status of multiple
initiatives in Asana. Portfolios provide a dashboard overview of
the state of multiple projects, including a progress report and the
most recent project status
update.
» color string false none Color of the portfolio.
» custom_field_settings [CustomFieldSettings] false read-only Array of custom field settings applied to the portfolio.
» owner any false none none

allOf

Name Type Required Restrictions Description
»» anonymous UserCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false read-only The current owner of the portfolio.

continued

Name Type Required Restrictions Description
» workspace any false none none

allOf

Name Type Required Restrictions Description
»» anonymous WorkspaceCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false none Create-only. The workspace or organization that the portfolio belongs to.

continued

Name Type Required Restrictions Description
» members any false none none

allOf

Name Type Required Restrictions Description
»» anonymous UserArray false none none

and

Name Type Required Restrictions Description
»» anonymous object false none Members of the portfolio

Enumerated Values

Property Value
color dark-pink
color dark-green
color dark-blue
color dark-red
color dark-teal
color dark-brown
color dark-orange
color dark-purple
color dark-warm-gray
color light-pink
color light-green
color light-blue
color light-red
color light-teal
color light-brown
color light-orange
color light-purple
color light-warm-gray

PortfolioCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "portfolio",
  "name": "Bug Task"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» resource_type string false none none

PortfolioObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "portfolio",
    "name": "Bug Task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "color": "light-green",
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "members": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ]
    }
  }
}

Properties

Name Type Required Restrictions Description
data Portfolio false none none

PortfolioArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "portfolio",
      "name": "Bug Task"
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [PortfolioCompact] false none none

Preview

{
  "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
  "footer": "Mar 17, 2019 1:25 PM",
  "header": "Asana for Slack",
  "header_link": "https://asana.comn/apps/slack",
  "html_text": "<body>Great! I like this idea.</body>",
  "text": "Great! I like this idea.",
  "title": "Greg",
  "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
}

A collection of rich text that will be displayed as a preview to another app.

This is read-only except for a small group of whitelisted apps.

Properties

Name Type Required Restrictions Description
fallback string false none Some fallback text to display if unable to display the full preview.
footer string false none Text to display in the footer.
header string false none Text to display in the header.
header_link string false none Where the header will link to.
html_text string false none HTML formatted text for the body of the preview.
text string false none Text for the body of the preview.
title string false none Text to display as the title.
title_link string false none Where to title will link to.

Project

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "project",
  "name": "Stuff to buy",
  "created_at": "2012-02-22T02:06:58.147Z",
  "archived": false,
  "color": "light-green",
  "current_status": {
    "color": "green",
    "text": "Everything is great",
    "author": {
      "id": 12345,
      "name": "Greg Bizarro"
    }
  },
  "custom_fields": [],
  "custom_field_settings": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "is_important": false,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    }
  ],
  "due_date": "2012-03-26",
  "due_on": "2012-03-26",
  "followers": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ],
  "html_notes": "These are things we need to purchase.",
  "is_template": false,
  "layout": "list",
  "members": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ],
  "modified_at": "2012-02-22T02:06:58.147Z",
  "notes": "These are things we need to purchase.",
  "owner": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "public": false,
  "section_migration_status": "not_migrated",
  "start_on": "2012-03-26",
  "team": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "workspace": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous ProjectCompact false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous object false none A project represents a prioritized list of tasks in Asana or a board
with columns of tasks represented as cards. It exists in a single
workspace or organization and is accessible to a subset of users in that
workspace or organization, depending on its permissions.

Projects in organizations are shared with a single team. You cannot
currently change the team of a project via the API. Non-organization
workspaces do not have teams and so you should not specify the team of
project in a regular workspace.

Followers of a project are a subset of the members of that project.
Followers of a project will receive all updates including tasks created,
added and removed from that project. Members of the project have access
to and will receive status updates of the project. Adding followers to a
project will add them as members if they are not already, removing
followers from a project will not affect membership.
» archived boolean false none True if the project is archived, false if not. Archived projects do not show in the UI by default and may be treated differently for queries.
» color string¦null false none Color of the project.
» current_status object¦null false read-only The most recently created status update for the project, or null if no update exists. See also the documentation for project status updates.
»» color string false none none
»» text string false none none
»» author User false none none
» custom_fields [CustomFieldSetting] false read-only Array of Custom Fields.
» custom_field_settings [CustomFieldSettings] false read-only Array of Custom Field Settings (in compact form).
» due_date string(date-time)¦null false none Deprecated: new integrations should prefer the due_on field.
» due_on string(date-time)¦null false none The day on which this project is due. This takes a date with format YYYY-MM-DD.
» followers [User] false read-only Array of users following this project. Followers are a subset of members who receive all notifications for a project, the default notification setting when adding members to a project in-product.
» html_notes string false none Opt In. The notes of the project with formatting as HTML.
Note: This field is under active migration—please see our blog post for more information.
» is_template boolean false none Opt In. Determines if the project is a template.
» layout string false read-only The layout (board or list view) of a project
» members [User] false read-only Array of users who are members of this project.
» modified_at string(date-time) false none The time at which this project was last modified.
Note: This does not currently reflect any changes in associations such as tasks or comments that may have been added or removed from the project.
» notes string false none More detailed, free-form textual information associated with the project.
» owner any false none none

allOf

Name Type Required Restrictions Description
»» anonymous UserCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object¦null false none The current owner of the project, may be null.

continued

Name Type Required Restrictions Description
» public boolean false none True if the project is public to the organization. If false, do not share this project with other users in this organization without explicitly checking to see if they have access.
» section_migration_status string false read-only Read-only The section migration status of this project.
» start_on string(date)¦null false none The day on which work for this project begins, or null if the project has no start date. This takes a date with YYYY-MM-DD format. Note: due_on or due_at must be present in the request when setting or unsetting the start_on parameter.
» team any false none none

allOf

Name Type Required Restrictions Description
»» anonymous TeamCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false none Create-only. The team that this project is shared with. This field only exists for projects in organizations.

continued

Name Type Required Restrictions Description
» workspace any false none none

allOf

Name Type Required Restrictions Description
»» anonymous WorkspaceCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false none Create-only. The workspace or organization this project is associated with. Once created, projects cannot be moved to a different workspace. This attribute can only be specified at creation time.

Enumerated Values

Property Value
color dark-pink
color dark-green
color dark-blue
color dark-red
color dark-teal
color dark-brown
color dark-orange
color dark-purple
color dark-warm-gray
color light-pink
color light-green
color light-blue
color light-red
color light-teal
color light-brown
color light-orange
color light-purple
color light-warm-gray
color green
color yellow
color red
layout list
layout board
section_migration_status not_migrated
section_migration_status in_progress
section_migration_status completed

ProjectCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "project",
  "name": "Stuff to buy"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» resource_type string false none none
» name string false none Name of the project. This is generally a short sentence fragment that fits on a line in the UI for maximum readability. However, it can be longer.

ProjectObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy",
    "created_at": "2012-02-22T02:06:58.147Z",
    "archived": false,
    "color": "light-green",
    "current_status": {
      "color": "green",
      "text": "Everything is great",
      "author": {
        "id": 12345,
        "name": "Greg Bizarro"
      }
    },
    "custom_fields": [],
    "custom_field_settings": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "is_important": false,
        "parent": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "custom_field": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      }
    ],
    "due_date": "2012-03-26",
    "due_on": "2012-03-26",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "html_notes": "These are things we need to purchase.",
    "is_template": false,
    "layout": "list",
    "members": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "These are things we need to purchase.",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "public": false,
    "section_migration_status": "not_migrated",
    "start_on": "2012-03-26",
    "team": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data Project false none none

ProjectArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy",
      "created_at": "2012-02-22T02:06:58.147Z",
      "archived": false,
      "color": "light-green",
      "current_status": {
        "color": "green",
        "text": "Everything is great",
        "author": {
          "id": 12345,
          "name": "Greg Bizarro"
        }
      },
      "custom_fields": [],
      "custom_field_settings": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "is_important": false,
          "parent": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "custom_field": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "resource_subtype": "milestone",
            "type": "text",
            "enum_options": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              }
            ],
            "enum_value": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            },
            "enabled": true,
            "text_value": "Some Value",
            "description": "Development team priority",
            "precision": 2
          }
        }
      ],
      "due_date": "2012-03-26",
      "due_on": "2012-03-26",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "html_notes": "These are things we need to purchase.",
      "is_template": false,
      "layout": "list",
      "members": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "These are things we need to purchase.",
      "owner": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "public": false,
      "section_migration_status": "not_migrated",
      "start_on": "2012-03-26",
      "team": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Project] false none none

ProjectMembership

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "user": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "project": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy"
  },
  "write_access": "full_write"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous ProjectMembershipCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none With the introduction of “comment-only” projects in Asana, a user’s membership in a project comes with associated permissions. These permissions (whether a user has full access to the project or comment-only access) are accessible through the project memberships endpoints described here.
» project ProjectCompact false none Opt In. The project the user is a member of.
» write_access string false read-only Whether the user has full access to the project or has comment-only access.

Enumerated Values

Property Value
write_access full_write
write_access comment_only

ProjectMembershipCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "user": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous object false none none
» user UserCompact false none none

ProjectMembershipObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "user": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "write_access": "full_write"
  }
}

Properties

Name Type Required Restrictions Description
data ProjectMembership false none none

ProjectMembershipArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "user": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "write_access": "full_write"
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [ProjectMembership] false none none

ProjectStatus

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "title": "Status Update - Jun 15",
  "created_at": "2012-02-22T02:06:58.147Z",
  "created_by": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  },
  "text": "The project is moving forward according to plan...",
  "html-text": "'&lt;body&gt;The project &lt;strong&gt;is&lt;/strong&gt; moving forward according to plan...&lt;/body&gt;'",
  "color": "green"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous ProjectStatusCompact false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedByAndAt false none none

and

Name Type Required Restrictions Description
anonymous object false none A project status is an update on the progress of a particular project, and is sent out to all project followers when created. These updates include both text describing the update and a color code intended to represent the overall state of the project: "green" for projects that are on track, "yellow" for projects at risk, and "red" for projects that are behind.
Project statuses can be created and deleted, but not modified.
» text string false read-only The text content of the status update.
» html-text string false read-only Opt In. The text content of the status update with formatting as HTML.
» color string false read-only The color associated with the status update.

Enumerated Values

Property Value
color green
color yellow
color red

ProjectStatusCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "title": "Status Update - Jun 15"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous object false none none
» title string false read-only The title of the project status update.

ProjectStatusObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "title": "Status Update - Jun 15",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "The project is moving forward according to plan...",
    "html-text": "'&lt;body&gt;The project &lt;strong&gt;is&lt;/strong&gt; moving forward according to plan...&lt;/body&gt;'",
    "color": "green"
  }
}

Properties

Name Type Required Restrictions Description
data ProjectStatus false none none

ProjectStatusArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "title": "Status Update - Jun 15",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "The project is moving forward according to plan...",
      "html-text": "'&lt;body&gt;The project &lt;strong&gt;is&lt;/strong&gt; moving forward according to plan...&lt;/body&gt;'",
      "color": "green"
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [ProjectStatus] false none none

Section

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Next Actions",
  "created_at": "2012-02-22T02:06:58.147Z",
  "projects": {
    "data": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy",
        "created_at": "2012-02-22T02:06:58.147Z",
        "archived": false,
        "color": "light-green",
        "current_status": {
          "color": "green",
          "text": "Everything is great",
          "author": {
            "id": 12345,
            "name": "Greg Bizarro"
          }
        },
        "custom_fields": [],
        "custom_field_settings": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "project": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "project",
              "name": "Stuff to buy"
            },
            "is_important": false,
            "parent": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "project",
              "name": "Stuff to buy"
            },
            "custom_field": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "resource_subtype": "milestone",
              "type": "text",
              "enum_options": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Low",
                  "enabled": true,
                  "color": "blue"
                }
              ],
              "enum_value": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Low",
                "enabled": true,
                "color": "blue"
              },
              "enabled": true,
              "text_value": "Some Value",
              "description": "Development team priority",
              "precision": 2
            }
          }
        ],
        "due_date": "2012-03-26",
        "due_on": "2012-03-26",
        "followers": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez",
            "email": "gsanchez@example.com",
            "photo": {
              "image_21x21": "https://...",
              "image_27x27": "https://...",
              "image_36x36": "https://...",
              "image_60x60": "https://...",
              "image_128x128": "https://..."
            },
            "workspaces": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Bug Task",
                "email_domains": [
                  "asana.com"
                ],
                "is_organization": false
              }
            ]
          }
        ],
        "html_notes": "These are things we need to purchase.",
        "is_template": false,
        "layout": "list",
        "members": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez",
            "email": "gsanchez@example.com",
            "photo": {
              "image_21x21": "https://...",
              "image_27x27": "https://...",
              "image_36x36": "https://...",
              "image_60x60": "https://...",
              "image_128x128": "https://..."
            },
            "workspaces": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Bug Task",
                "email_domains": [
                  "asana.com"
                ],
                "is_organization": false
              }
            ]
          }
        ],
        "modified_at": "2012-02-22T02:06:58.147Z",
        "notes": "These are things we need to purchase.",
        "owner": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        },
        "public": false,
        "section_migration_status": "not_migrated",
        "start_on": "2012-03-26",
        "team": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task"
        },
        "workspace": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task"
        }
      }
    ]
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous SectionCompact false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous object false none A section is a subdivision of a project that groups tasks together. It
can either be a header above a list of tasks in a list view or a column
in a board view of a project.

Sections are largely a shared idiom in Asana’s API for both list and
board views of a project regardless of the project’s layout.

The ‘memberships’ property when getting a
task
will return
the information for the section or the column under ‘section’ in the
response.
» projects ProjectArray false none none

SectionCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Next Actions"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous object false none none
» name string false none The name of the section (i.e. the text displayed as the section header).

SectionObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Next Actions",
    "created_at": "2012-02-22T02:06:58.147Z",
    "projects": {
      "data": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy",
          "created_at": "2012-02-22T02:06:58.147Z",
          "archived": false,
          "color": "light-green",
          "current_status": {
            "color": "green",
            "text": "Everything is great",
            "author": {
              "id": 12345,
              "name": "Greg Bizarro"
            }
          },
          "custom_fields": [],
          "custom_field_settings": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "project": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "is_important": false,
              "parent": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "project",
                "name": "Stuff to buy"
              },
              "custom_field": {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Bug Task",
                "resource_subtype": "milestone",
                "type": "text",
                "enum_options": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Low",
                    "enabled": true,
                    "color": "blue"
                  }
                ],
                "enum_value": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Low",
                  "enabled": true,
                  "color": "blue"
                },
                "enabled": true,
                "text_value": "Some Value",
                "description": "Development team priority",
                "precision": 2
              }
            }
          ],
          "due_date": "2012-03-26",
          "due_on": "2012-03-26",
          "followers": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "html_notes": "These are things we need to purchase.",
          "is_template": false,
          "layout": "list",
          "members": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez",
              "email": "gsanchez@example.com",
              "photo": {
                "image_21x21": "https://...",
                "image_27x27": "https://...",
                "image_36x36": "https://...",
                "image_60x60": "https://...",
                "image_128x128": "https://..."
              },
              "workspaces": [
                {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "email_domains": [
                    "asana.com"
                  ],
                  "is_organization": false
                }
              ]
            }
          ],
          "modified_at": "2012-02-22T02:06:58.147Z",
          "notes": "These are things we need to purchase.",
          "owner": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez"
          },
          "public": false,
          "section_migration_status": "not_migrated",
          "start_on": "2012-03-26",
          "team": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          },
          "workspace": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task"
          }
        }
      ]
    }
  }
}

Properties

Name Type Required Restrictions Description
data Section false none none

SectionArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions",
      "created_at": "2012-02-22T02:06:58.147Z",
      "projects": {
        "data": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy",
            "created_at": "2012-02-22T02:06:58.147Z",
            "archived": false,
            "color": "light-green",
            "current_status": {
              "color": "green",
              "text": "Everything is great",
              "author": {
                "id": 12345,
                "name": "Greg Bizarro"
              }
            },
            "custom_fields": [],
            "custom_field_settings": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "project": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "project",
                  "name": "Stuff to buy"
                },
                "is_important": false,
                "parent": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "project",
                  "name": "Stuff to buy"
                },
                "custom_field": {
                  "id": 12345,
                  "gid": "12345",
                  "resource_type": "task",
                  "name": "Bug Task",
                  "resource_subtype": "milestone",
                  "type": "text",
                  "enum_options": [
                    {}
                  ],
                  "enum_value": {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Low",
                    "enabled": true,
                    "color": "blue"
                  },
                  "enabled": true,
                  "text_value": "Some Value",
                  "description": "Development team priority",
                  "precision": 2
                }
              }
            ],
            "due_date": "2012-03-26",
            "due_on": "2012-03-26",
            "followers": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Greg Sanchez",
                "email": "gsanchez@example.com",
                "photo": {
                  "image_21x21": "https://...",
                  "image_27x27": "https://...",
                  "image_36x36": "https://...",
                  "image_60x60": "https://...",
                  "image_128x128": "https://..."
                },
                "workspaces": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Bug Task",
                    "email_domains": [],
                    "is_organization": false
                  }
                ]
              }
            ],
            "html_notes": "These are things we need to purchase.",
            "is_template": false,
            "layout": "list",
            "members": [
              {
                "id": 12345,
                "gid": "12345",
                "resource_type": "task",
                "name": "Greg Sanchez",
                "email": "gsanchez@example.com",
                "photo": {
                  "image_21x21": "https://...",
                  "image_27x27": "https://...",
                  "image_36x36": "https://...",
                  "image_60x60": "https://...",
                  "image_128x128": "https://..."
                },
                "workspaces": [
                  {
                    "id": 12345,
                    "gid": "12345",
                    "resource_type": "task",
                    "name": "Bug Task",
                    "email_domains": [],
                    "is_organization": false
                  }
                ]
              }
            ],
            "modified_at": "2012-02-22T02:06:58.147Z",
            "notes": "These are things we need to purchase.",
            "owner": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Greg Sanchez"
            },
            "public": false,
            "section_migration_status": "not_migrated",
            "start_on": "2012-03-26",
            "team": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task"
            },
            "workspace": {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task"
            }
          }
        ]
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Section] false none none

Story

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "resource_subtype": "milestone",
  "created_at": "2012-02-22T02:06:58.147Z",
  "created_by": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  },
  "text": "marked today",
  "type": "comment",
  "html_text": "Get whatever Sashimi has.",
  "is_edited": false,
  "is_pinned": false,
  "hearted": false,
  "hearts": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ],
  "num_hearts": 5,
  "liked": false,
  "likes": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ],
  "num_likes": 5,
  "previews": [
    {
      "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
      "footer": "Mar 17, 2019 1:25 PM",
      "header": "Asana for Slack",
      "header_link": "https://asana.comn/apps/slack",
      "html_text": "<body>Great! I like this idea.</body>",
      "text": "Great! I like this idea.",
      "title": "Greg",
      "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
    }
  ],
  "old_name": "This was the Old Name",
  "new_name": "This is the New Name",
  "old_dates": {
    "start_on": "2019-09-15",
    "due_at": "2012-02-22T02:06:58.158Z",
    "due_on": "2019-09-15"
  },
  "new_dates": {
    "start_on": "2019-09-15",
    "due_at": "2012-02-22T02:06:58.158Z",
    "due_on": "2019-09-15"
  },
  "old_resource_subtype": "default_task",
  "new_resource_subtype": "milestone",
  "story": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "marked today",
    "type": "comment"
  },
  "assignee": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "follower": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "old_section": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Next Actions"
  },
  "new_section": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Next Actions"
  },
  "task": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "project": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "project",
    "name": "Stuff to buy"
  },
  "tag": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Stuff to buy"
  },
  "custom_field": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "resource_subtype": "milestone",
    "type": "text",
    "enum_options": [],
    "enum_value": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Low",
      "enabled": true,
      "color": "blue"
    },
    "enabled": true,
    "text_value": "Some Value"
  },
  "old_text_value": "This was the Old Text",
  "new_text_value": "This is the New Text",
  "old_number_value": 1,
  "new_number_value": 2,
  "old_enum_value": null,
  "new_enum_value": null,
  "duplicate_of": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "duplicated_from": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "dependancy": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "source": "web",
  "target": {
    "id": 1234,
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous StoryCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none See our forum post for
more info on when conditional fields are returned.

A story represents an activity associated with an object in the Asana
system. Stories are generated by the system whenever users take actions
such as creating or assigning tasks, or moving tasks between projects.
Comments are also a form of user-generated story.
» html_text string false none Opt In.
HTML formatted text for a comment. This will not include the name
of the creator.

Note: This field is under active migration—please see our blog
post for more information.
» is_edited boolean false none Conditional. Whether the text of the story has been edited after creation.
» is_pinned boolean false none Conditional. Whether the story should be pinned on the resource.
» hearted boolean false read-only Deprecated - please use likes instead

Conditional. True if the story is hearted by the authorized user, false if not.
» hearts [User] false read-only Deprecated - please use likes instead

Conditional. Array of users who have hearted this story.
» num_hearts integer false read-only Deprecated - please use likes instead

Conditional. The number of users who have hearted this story.
» liked boolean false read-only Conditional. True if the story is liked by the authorized user, false if not.
» likes [User] false read-only Conditional. Array of users who have liked this story.
» num_likes integer false read-only Conditional. The number of users who have liked this story.
» previews [Preview] false read-only Conditional. A collection of previews to be displayed in the story.

Note: This property only exists for comment stories.
» old_name string false none Conditional
» new_name string false none Conditional
» old_dates object false none Conditional
»» start_on string(date) false none none
»» due_at string(date-time) false none none
»» due_on string(date) false none none
» new_dates object false none Conditional
»» start_on string(date) false none none
»» due_at string(date-time) false none none
»» due_on string(date) false none none
» old_resource_subtype string false none Conditional
» new_resource_subtype string false none Conditional
» story StoryCompact false none Conditional
» assignee UserCompact false none Conditional
» follower UserCompact false none Conditional
» old_section SectionCompact false none Conditional
» new_section SectionCompact false none Conditional
» task TaskCompact false none Conditional
» project ProjectCompact false none Conditional
» tag TagCompact false none Conditional
» custom_field CustomFieldCompact false none Conditional
» old_text_value string false none Conditional
» new_text_value string false none Conditional
» old_number_value integer false none Conditional
» new_number_value integer false none Conditional
» old_enum_value EnumOptionCompact false none Conditional
» new_enum_value EnumOptionCompact false none Conditional
» duplicate_of TaskCompact false none Conditional
» duplicated_from TaskCompact false none Conditional
» dependancy TaskCompact false none Conditional
» source string false read-only The component of the Asana product the user used to trigger the story.
» target object false read-only The object this story is associated with. Currently may only be a task.
»» id integer false none none
»» name string false none none

StoryCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "resource_subtype": "milestone",
  "created_at": "2012-02-22T02:06:58.147Z",
  "created_by": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  },
  "text": "marked today",
  "type": "comment"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous AsanaSubtype false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedByAndAt false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» text any false none Create-only. Human-readable text for the story or comment.
This will not include the name of the creator.

Note: This is not guaranteed to be stable for a given type of
story. For example, text for a reassignment may not always say
“assigned to …” as the text for a story can both be edited and
change based on the language settings of the user making the request.
Use the resource_subtype property to discover the action that
created the story.
» type string false read-only Deprecated: new integrations should prefer the resource_subtype field. The type of this story. For more fine-grained inspection of story types, see the resource_subtype property.

StoryObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "resource_subtype": "milestone",
    "created_at": "2012-02-22T02:06:58.147Z",
    "created_by": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    },
    "text": "marked today",
    "type": "comment",
    "html_text": "Get whatever Sashimi has.",
    "is_edited": false,
    "is_pinned": false,
    "hearted": false,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_hearts": 5,
    "liked": false,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      }
    ],
    "num_likes": 5,
    "previews": [
      {
        "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
        "footer": "Mar 17, 2019 1:25 PM",
        "header": "Asana for Slack",
        "header_link": "https://asana.comn/apps/slack",
        "html_text": "<body>Great! I like this idea.</body>",
        "text": "Great! I like this idea.",
        "title": "Greg",
        "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
      }
    ],
    "old_name": "This was the Old Name",
    "new_name": "This is the New Name",
    "old_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "new_dates": {
      "start_on": "2019-09-15",
      "due_at": "2012-02-22T02:06:58.158Z",
      "due_on": "2019-09-15"
    },
    "old_resource_subtype": "default_task",
    "new_resource_subtype": "milestone",
    "story": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "resource_subtype": "milestone",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "marked today",
      "type": "comment"
    },
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "follower": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "old_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "new_section": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Next Actions"
    },
    "task": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "project": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    },
    "tag": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy"
    },
    "custom_field": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value"
    },
    "old_text_value": "This was the Old Text",
    "new_text_value": "This is the New Text",
    "old_number_value": 1,
    "new_number_value": 2,
    "old_enum_value": null,
    "new_enum_value": null,
    "duplicate_of": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "duplicated_from": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "dependancy": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "source": "web",
    "target": {
      "id": 1234,
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data Story false none none

StoryArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "resource_subtype": "milestone",
      "created_at": "2012-02-22T02:06:58.147Z",
      "created_by": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez",
        "email": "gsanchez@example.com",
        "photo": {
          "image_21x21": "https://...",
          "image_27x27": "https://...",
          "image_36x36": "https://...",
          "image_60x60": "https://...",
          "image_128x128": "https://..."
        },
        "workspaces": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Bug Task",
            "email_domains": [
              "asana.com"
            ],
            "is_organization": false
          }
        ]
      },
      "text": "marked today",
      "type": "comment",
      "html_text": "Get whatever Sashimi has.",
      "is_edited": false,
      "is_pinned": false,
      "hearted": false,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "num_hearts": 5,
      "liked": false,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        }
      ],
      "num_likes": 5,
      "previews": [
        {
          "fallback": "Greg: Great! I like this idea.\\n\\nhttps//a_company.slack.com/archives/ABCDEFG/12345678",
          "footer": "Mar 17, 2019 1:25 PM",
          "header": "Asana for Slack",
          "header_link": "https://asana.comn/apps/slack",
          "html_text": "<body>Great! I like this idea.</body>",
          "text": "Great! I like this idea.",
          "title": "Greg",
          "title_link": "https://asana.slack.com/archives/ABCDEFG/12345678"
        }
      ],
      "old_name": "This was the Old Name",
      "new_name": "This is the New Name",
      "old_dates": {
        "start_on": "2019-09-15",
        "due_at": "2012-02-22T02:06:58.158Z",
        "due_on": "2019-09-15"
      },
      "new_dates": {
        "start_on": "2019-09-15",
        "due_at": "2012-02-22T02:06:58.158Z",
        "due_on": "2019-09-15"
      },
      "old_resource_subtype": "default_task",
      "new_resource_subtype": "milestone",
      "story": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "resource_subtype": "milestone",
        "created_at": "2012-02-22T02:06:58.147Z",
        "created_by": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez",
          "email": "gsanchez@example.com",
          "photo": {
            "image_21x21": "https://...",
            "image_27x27": "https://...",
            "image_36x36": "https://...",
            "image_60x60": "https://...",
            "image_128x128": "https://..."
          },
          "workspaces": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Bug Task",
              "email_domains": [
                "asana.com"
              ],
              "is_organization": false
            }
          ]
        },
        "text": "marked today",
        "type": "comment"
      },
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "follower": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "old_section": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Next Actions"
      },
      "new_section": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Next Actions"
      },
      "task": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "tag": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value"
      },
      "old_text_value": "This was the Old Text",
      "new_text_value": "This is the New Text",
      "old_number_value": 1,
      "new_number_value": 2,
      "old_enum_value": null,
      "new_enum_value": null,
      "duplicate_of": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "duplicated_from": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "dependancy": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "source": "web",
      "target": {
        "id": 1234,
        "name": "Bug Task"
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data array false none none

Tag

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Stuff to buy",
  "followers": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    }
  ],
  "color": "light-green",
  "workspace": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous TagCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none A tag is a label that can be attached to any task in Asana. It exists
in a single workspace or organization.

Tags have some metadata associated with them, but it is possible that we
will simplify them in the future so it is not encouraged to rely too
heavily on it. Unlike projects, tags do not provide any ordering on the
tasks they are associated with.
» followers [UserCompact] false read-only Array of users following this tag.
» color string false none Color of the tag.
» workspace WorkspaceCompact false none none

Enumerated Values

Property Value
color dark-pink
color dark-green
color dark-blue
color dark-red
color dark-teal
color dark-brown
color dark-orange
color dark-purple
color dark-warm-gray
color light-pink
color light-green
color light-blue
color light-red
color light-teal
color light-brown
color light-orange
color light-purple
color light-warm-gray

TagCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Stuff to buy"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous object false none none
» name string false none Name of the tag. This is generally a short sentence fragment that fits on a line in the UI for maximum readability. However, it can be longer.

TagObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Stuff to buy",
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "color": "light-green",
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data Tag false none none

TagArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Stuff to buy",
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "color": "light-green",
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Tag] false none none

Task

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Buy catnip",
  "created_at": "2012-02-22T02:06:58.147Z",
  "resource_subtype": "default_task",
  "assignee": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "assignee_status": "upcoming",
  "completed": false,
  "completed_at": "2012-02-22T02:06:58.147Z",
  "custom_fields": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "resource_subtype": "milestone",
      "type": "text",
      "enum_options": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        }
      ],
      "enum_value": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Low",
        "enabled": true,
        "color": "blue"
      },
      "enabled": true,
      "text_value": "Some Value",
      "description": "Development team priority",
      "precision": 2
    }
  ],
  "dependencies": [
    {
      "id": 1234,
      "gid": "1234"
    },
    {
      "id": 4321,
      "gid": "4321"
    }
  ],
  "dependents": [
    {
      "id": 1234,
      "gid": "1234"
    },
    {
      "id": 4321,
      "gid": "4321"
    }
  ],
  "due_at": "2012-02-22T02:06:58.147Z",
  "due_on": "2012-03-26",
  "external": {
    "id": "my_id",
    "data": "A blob of information"
  },
  "followers": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    }
  ],
  "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
  "hearted": true,
  "hearts": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    }
  ],
  "liked": true,
  "likes": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    }
  ],
  "memberships": [
    {
      "project": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      },
      "section": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Next Actions"
      }
    }
  ],
  "modified_at": "2012-02-22T02:06:58.147Z",
  "notes": "Mittens really likes the stuff from Humboldt.",
  "num_hearts": 5,
  "num_likes": 5,
  "num_subtasks": 3,
  "parent": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "projects": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "project",
      "name": "Stuff to buy"
    }
  ],
  "start_on": "2012-03-26",
  "tags": [
    {
      "id": 59746,
      "gid": "59746",
      "name": "Grade A"
    }
  ],
  "workspace": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous TaskCompact false none none

and

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous AsanaSubtype false none none

and

Name Type Required Restrictions Description
anonymous object false none The task is the basic object around which many operations in Asana are
centered. In the Asana application, multiple tasks populate the middle
pane according to some view parameters, and the set of selected tasks
determines the more detailed information presented in the details pane.

A section, at its core, is a task whose name ends with the colon
character :. Sections are unique in that they will be included in the
memberships field of task objects returned in the API when the task is
within a section. They can also be used to manipulate the ordering of a
task within a project.

Queries return
a compact representation of each object which is typically the id and
name fields. Interested in a specific set of fields or all of the fields?
Use field
selectors

to manipulate what data is included in a response.
» assignee any false none none

allOf

Name Type Required Restrictions Description
»» anonymous UserCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object¦null false none none

continued

Name Type Required Restrictions Description
» assignee_status string false none Scheduling status of this task for the user it is assigned to. This field can only be set if the assignee is non-null.
» completed boolean false none True if the task is currently marked complete, false if not.
» completed_at string(date-time)¦null false read-only The time at which this task was completed, or null if the task is incomplete.
» custom_fields [CustomField] false read-only Array of custom field values applied to the project. These represent
the custom field values recorded on this project for a particular
custom field. For example, these custom field values will contain
an enum_value property for custom fields of type enum, a
string_value property for custom fields of type string, and
so on. Please note that the id returned on each custom field
value is identical to the id of the custom field, which
allows referencing the custom field metadata through the
/custom_fields/custom_field-id endpoint.
» dependencies [object] false read-only Opt In. Array of resources referencing tasks that this task depends on. The objects contain only the ID of the dependency.
»» id integer false none none
»» gid string false none none
» dependents [object] false read-only Opt In. Array of resources referencing tasks that depend on this task. The objects contain only the ID of the dependent.
»» id integer false none none
»» gid string false none none
» due_at string(date)¦null false none Date and time on which this task is due, or null if the task has no due time. This takes a UTC timestamp and should not be used together with due_on.
» due_on string(date)¦null false none Date on which this task is due, or null if the task has no due date. This takes a date with YYYY-MM-DD format and should not be used together with due_at.
» external object false none OAuth Required. Conditional. This field is returned only if external values are set or included by using Opt In.
The external field allows you to store app-specific metadata on tasks, including an id that can be used to retrieve tasks and a data blob that can store app-specific character strings. Note that you will need to authenticate with Oauth to access or modify this data. Once an external id is set, you can use the notation external:custom_id to reference your object anywhere in the API where you may use the original object id. See the page on Custom External Data for more details.
»» id integer false none none
»» gid string false none none
»» data string false none none
» followers [UserCompact] false none Array of users following this task.
» html_notes string false none Opt In. The notes of the text with formatting as HTML.
Note: This field is under active migration—please see our blog post for more information.
» hearted boolean false read-only Deprecated - please use liked instead True if the task is hearted by the authorized user, false if not.
» hearts [UserCompact] false read-only Deprecated - please use likes instead Array of users who have hearted this task.
» liked boolean false read-only True if the task is liked by the authorized user, false if not.
» likes [UserCompact] false read-only Array of users who have liked this task.
» memberships [object] false none Create-only. Array of projects this task is associated with and the section it is in. At task creation time, this array can be used to add the task to specific sections. After task creation, these associations can be modified using the addProject and removeProject endpoints. Note that over time, more types of memberships may be added to this property.
»» project ProjectCompact false none none
»» section SectionCompact false none none
» modified_at string(date-time) false read-only The time at which this task was last modified.

Note: This does not currently reflect any changes in
associations such as projects or comments that may have been
added or removed from the task.
» name string false none Name of the task. This is generally a short sentence fragment that fits on a line in the UI for maximum readability. However, it can be longer.
» notes string false none More detailed, free-form textual information associated with the task.
» num_hearts integer false read-only Deprecated - please use likes instead The number of users who have hearted this task.
» num_likes integer false read-only The number of users who have liked this task.
» num_subtasks integer false read-only Opt In. The number of subtasks on this task.
» parent any false none none

allOf

Name Type Required Restrictions Description
»» anonymous TaskCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object¦null false none The parent of this task, or null if this is not a subtask. This property cannot be modified using a PUT request but you can change it with the setParent endpoint. You can create subtasks by using the subtasks endpoint.

continued

Name Type Required Restrictions Description
» projects [ProjectCompact] false none Create-only. Array of projects this task is associated with. At task creation time, this array can be used to add the task to many projects at once. After task creation, these associations can be modified using the addProject and removeProject endpoints.
» resource_subtype string false none none
» start_on string(date)¦null false none The day on which work begins for the task , or null if the task has
no start date. This takes a date with YYYY-MM-DD format.

Note: due_on or due_at must be present in the request when
setting or unsetting the start_on parameter.
» tags [Tag] false none Create-only. Array of tags associated with this task. This property may be specified on creation using just an array of tag IDs. In order to change tags on an existing task use addTag and removeTag.
» workspace any false none none

allOf

Name Type Required Restrictions Description
»» anonymous WorkspaceCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false none Create-only. The workspace this task is associated with. Once created, task cannot be moved to a different workspace. This attribute can only be specified at creation time.

Enumerated Values

Property Value
assignee_status today
assignee_status upcoming
assignee_status later
assignee_status new
assignee_status inbox
resource_subtype default_task
resource_subtype milestone
resource_subtype section

TaskCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task"
}

Properties

None

TaskObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Buy catnip",
    "created_at": "2012-02-22T02:06:58.147Z",
    "resource_subtype": "default_task",
    "assignee": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "assignee_status": "upcoming",
    "completed": false,
    "completed_at": "2012-02-22T02:06:58.147Z",
    "custom_fields": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "resource_subtype": "milestone",
        "type": "text",
        "enum_options": [
          {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enum_value": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "enabled": true,
        "text_value": "Some Value",
        "description": "Development team priority",
        "precision": 2
      }
    ],
    "dependencies": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "dependents": [
      {
        "id": 1234,
        "gid": "1234"
      },
      {
        "id": 4321,
        "gid": "4321"
      }
    ],
    "due_at": "2012-02-22T02:06:58.147Z",
    "due_on": "2012-03-26",
    "external": {
      "id": "my_id",
      "data": "A blob of information"
    },
    "followers": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
    "hearted": true,
    "hearts": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "liked": true,
    "likes": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      }
    ],
    "memberships": [
      {
        "project": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        },
        "section": {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Next Actions"
        }
      }
    ],
    "modified_at": "2012-02-22T02:06:58.147Z",
    "notes": "Mittens really likes the stuff from Humboldt.",
    "num_hearts": 5,
    "num_likes": 5,
    "num_subtasks": 3,
    "parent": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "projects": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "project",
        "name": "Stuff to buy"
      }
    ],
    "start_on": "2012-03-26",
    "tags": [
      {
        "id": 59746,
        "gid": "59746",
        "name": "Grade A"
      }
    ],
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data Task false none none

TaskArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Buy catnip",
      "created_at": "2012-02-22T02:06:58.147Z",
      "resource_subtype": "default_task",
      "assignee": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Greg Sanchez"
      },
      "assignee_status": "upcoming",
      "completed": false,
      "completed_at": "2012-02-22T02:06:58.147Z",
      "custom_fields": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "resource_subtype": "milestone",
          "type": "text",
          "enum_options": [
            {
              "id": 12345,
              "gid": "12345",
              "resource_type": "task",
              "name": "Low",
              "enabled": true,
              "color": "blue"
            }
          ],
          "enum_value": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          },
          "enabled": true,
          "text_value": "Some Value",
          "description": "Development team priority",
          "precision": 2
        }
      ],
      "dependencies": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "dependents": [
        {
          "id": 1234,
          "gid": "1234"
        },
        {
          "id": 4321,
          "gid": "4321"
        }
      ],
      "due_at": "2012-02-22T02:06:58.147Z",
      "due_on": "2012-03-26",
      "external": {
        "id": "my_id",
        "data": "A blob of information"
      },
      "followers": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
      "hearted": true,
      "hearts": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "liked": true,
      "likes": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        }
      ],
      "memberships": [
        {
          "project": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "project",
            "name": "Stuff to buy"
          },
          "section": {
            "id": 12345,
            "gid": "12345",
            "resource_type": "task",
            "name": "Next Actions"
          }
        }
      ],
      "modified_at": "2012-02-22T02:06:58.147Z",
      "notes": "Mittens really likes the stuff from Humboldt.",
      "num_hearts": 5,
      "num_likes": 5,
      "num_subtasks": 3,
      "parent": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "projects": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "project",
          "name": "Stuff to buy"
        }
      ],
      "start_on": "2012-03-26",
      "tags": [
        {
          "id": 59746,
          "gid": "59746",
          "name": "Grade A"
        }
      ],
      "workspace": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Task] false none none

Team

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task",
  "description": "All developers should be members of this team.",
  "html_description": "<body><em>All</em> developers should be members of this team.</body>",
  "organization": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous TeamCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none A team is used to group related projects and people together within an
organization. Each project in an organization is associated with a team.
» description string false none Opt In. The description of the team.
» html_description string false none Opt In. The description of the team with formatting as HTML.
Note: This field is under active migration—please see our blog post for more information.
» organization any false none none

allOf

Name Type Required Restrictions Description
»» anonymous WorkspaceCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false none The organization/workspace the team belongs to.

TeamCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task"
}

Properties

None

TeamObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "description": "All developers should be members of this team.",
    "html_description": "<body><em>All</em> developers should be members of this team.</body>",
    "organization": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data Team false none none

TeamArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "description": "All developers should be members of this team.",
      "html_description": "<body><em>All</em> developers should be members of this team.</body>",
      "organization": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      }
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Team] false none none

User

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Greg Sanchez",
  "email": "gsanchez@example.com",
  "photo": {
    "image_21x21": "https://...",
    "image_27x27": "https://...",
    "image_36x36": "https://...",
    "image_60x60": "https://...",
    "image_128x128": "https://..."
  },
  "workspaces": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "email_domains": [
        "asana.com"
      ],
      "is_organization": false
    }
  ]
}

Properties

allOf

Name Type Required Restrictions Description
anonymous UserCompact false none none

and

Name Type Required Restrictions Description
anonymous object false none A user object represents an account in Asana that can be given access
to various workspaces, projects, and tasks.

Like other objects in the system, users are referred to by numerical
IDs. However, the special string identifier me can be used anywhere a
user ID is accepted, to refer to the current authenticated user.
» email string(email) false read-only The user’s email address.
» photo object¦null false read-only A map of the user’s profile photo in various sizes, or null if no photo is set. Sizes provided are 21, 27, 36, 60, and 128. Images are in PNG format.
»» image_21x21 string(uri) false none none
»» image_27x27 string(uri) false none none
»» image_36x36 string(uri) false none none
»» image_60x60 string(uri) false none none
»» image_128x128 string(uri) false none none
» workspaces [Workspace] false read-only Workspaces and organizations this user may access.
Note: The API will only return workspaces and organizations that also contain the authenticated user.

UserCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Greg Sanchez"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
anonymous object false none none
» name string false none Read-only except when same user as requester. The user’s name.

UserObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez",
    "email": "gsanchez@example.com",
    "photo": {
      "image_21x21": "https://...",
      "image_27x27": "https://...",
      "image_36x36": "https://...",
      "image_60x60": "https://...",
      "image_128x128": "https://..."
    },
    "workspaces": [
      {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task",
        "email_domains": [
          "asana.com"
        ],
        "is_organization": false
      }
    ]
  }
}

Properties

Name Type Required Restrictions Description
data User false none none

UserArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez",
      "email": "gsanchez@example.com",
      "photo": {
        "image_21x21": "https://...",
        "image_27x27": "https://...",
        "image_36x36": "https://...",
        "image_60x60": "https://...",
        "image_128x128": "https://..."
      },
      "workspaces": [
        {
          "id": 12345,
          "gid": "12345",
          "resource_type": "task",
          "name": "Bug Task",
          "email_domains": [
            "asana.com"
          ],
          "is_organization": false
        }
      ]
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [User] false none none

UserIdObject

{
  "data": {
    "user": 12345
  }
}

A user ID object for specification with the addUser/removeUser endpoints.

Properties

Name Type Required Restrictions Description
data object false none none
» user any false none none

oneOf

Name Type Required Restrictions Description
»» anonymous integer false none none

xor

Name Type Required Restrictions Description
»» anonymous string false none none

xor

Name Type Required Restrictions Description
»» anonymous string(email) false none none

Enumerated Values

Property Value
anonymous me

UserTaskList

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task",
  "owner": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Greg Sanchez"
  },
  "workspace": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  }
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
anonymous object false none A user task list represents the tasks assigned to a particular user. It provides API access to a user’s “My Tasks” view in Asana.
A user’s “My Tasks” represent all of the tasks assigned to that user. It is visually divided into regions based on the task’s assignee_status for Asana users to triage their tasks based on when they can address them. When building an integration it’s worth noting that tasks with due dates will automatically move through assignee_status states as their due dates approach; read up on task auto-promotion for more information.
» owner any false none none

allOf

Name Type Required Restrictions Description
»» anonymous UserCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false read-only The owner of the user task list, i.e. the person whose My Tasks is represented by this resource.

continued

Name Type Required Restrictions Description
» workspace any false none none

allOf

Name Type Required Restrictions Description
»» anonymous WorkspaceCompact false none none

and

Name Type Required Restrictions Description
»» anonymous object false read-only The workspace in which the user task list is located.

UserTaskListObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "owner": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Greg Sanchez"
    },
    "workspace": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    }
  }
}

Properties

Name Type Required Restrictions Description
data UserTaskList false none none

Webhook

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "created_at": "2012-02-22T02:06:58.147Z",
  "active": false,
  "last_failure_at": "2012-02-22T02:06:58.147Z",
  "last_failure_content": "500 Server Error\\n\\nCould not complete the request",
  "last_success_at": "2012-02-22T02:06:58.147Z",
  "resource": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task"
  },
  "target": "https://example.com/receive-webhook/7654"
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaObject false none A generic Asana Object, containing a globally unique identifier.

and

Name Type Required Restrictions Description
anonymous AsanaCreatedAt false none none

and

Name Type Required Restrictions Description
anonymous object false none Webhooks allow an application to be notified of changes. This is in
addition to the ability to fetch those changes directly as Events - in
fact, Webhooks are just a way to receive
Events via HTTP POST
at the time they occur instead of polling for them. For services
accessible via HTTP this is often vastly more convenient, and if events
are not too frequent can be significantly more efficient.

In both cases, however, changes are represented as Event objects - refer
to the Events
documentation
for
more information on what data these events contain.

Note: While Webhooks send arrays of Event objects to their target,
the Event objects themselves contain only IDs, rather than the actual
resource they are referencing. Webhooks themselves contain only the
information necessary to deliver the events to the desired target as they
are generated.
» active boolean false none If true, the webhook will send events - if false it is considered inactive and will not generate events.
» last_failure_at string(date-time) false read-only The timestamp when the webhook last received an error when sending an event to the target.
» last_failure_content string false read-only The contents of the last error response sent to the webhook when attempting to deliver events to the target.
» last_success_at string(date-time) false read-only The timestamp when the webhook last successfully sent an event to the target.
» resource any false none none

allOf

Name Type Required Restrictions Description
»» anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
»» anonymous object false none The resource the webhook is subscribed to.

continued

Name Type Required Restrictions Description
» target string(uri) false read-only The URL to receive the HTTP POST.

WebhookEvent

{
  "action": "changed",
  "created_at": "2012-02-22T02:06:58.147Z",
  "parent": 12345,
  "resource": 32154,
  "type": "task",
  "user": 321654987
}

Properties

Name Type Required Restrictions Description
action string false read-only The type of action taken that triggered the event.
created_at string(date-time) false read-only The timestamp when the event occurred.
parent integer¦null false read-only For added/removed events, the parent ID that resource was added to or removed from. The parent will be null for other event types.
resource integer false read-only The resource ID the event occurred on.

Note: The resource that triggered the event may be different from
the one that the events were requested for. For example, a
subscription to a project will contain events for tasks contained
within the project.
type string false read-only The type of the resource that generated the event.

Note: Currently, only tasks, projects and stories generate
events.
user integer¦null false read-only The ID of the user who triggered the event.

Note: The event may be triggered by a different user than the
subscriber. For example, if user A subscribes to a task and user B
modified it, the event’s user will be user B. Note: Some events are
generated by the system, and will have null as the user. API
consumers should make sure to handle this case.

WebhookObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "created_at": "2012-02-22T02:06:58.147Z",
    "active": false,
    "last_failure_at": "2012-02-22T02:06:58.147Z",
    "last_failure_content": "500 Server Error\\n\\nCould not complete the request",
    "last_success_at": "2012-02-22T02:06:58.147Z",
    "resource": {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task"
    },
    "target": "https://example.com/receive-webhook/7654"
  }
}

Properties

Name Type Required Restrictions Description
data Webhook false none none

WebhookArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "created_at": "2012-02-22T02:06:58.147Z",
      "active": false,
      "last_failure_at": "2012-02-22T02:06:58.147Z",
      "last_failure_content": "500 Server Error\\n\\nCould not complete the request",
      "last_success_at": "2012-02-22T02:06:58.147Z",
      "resource": {
        "id": 12345,
        "gid": "12345",
        "resource_type": "task",
        "name": "Bug Task"
      },
      "target": "https://example.com/receive-webhook/7654"
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Webhook] false none none

Workspace

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task",
  "email_domains": [
    "asana.com"
  ],
  "is_organization": false
}

Properties

allOf

Name Type Required Restrictions Description
anonymous AsanaNamedObject false none none

and

Name Type Required Restrictions Description
anonymous object false none A workspace is the highest-level organizational unit in Asana. All
projects and tasks have an associated workspace.

An organization is a special kind of workspace that represents a
company. In an organization, you can group your projects into teams.
You can read more about how organizations work on the Asana Guide. To
tell if your workspace is an organization or not, check its
is_organization property.

Over time, we intend to migrate most workspaces into organizations and
to release more organization-specific functionality. We may eventually
deprecate using workspace-based APIs for organizations. Currently, and
until after some reasonable grace period following any further
announcements, you can still reference organizations in any workspace
parameter.
» email_domains [string] false none The email domains that are associated with this workspace.
» is_organization boolean false none Whether the workspace is an organization.

WorkspaceCompact

{
  "id": 12345,
  "gid": "12345",
  "resource_type": "task",
  "name": "Bug Task"
}

Properties

None

WorkspaceObject

{
  "data": {
    "id": 12345,
    "gid": "12345",
    "resource_type": "task",
    "name": "Bug Task",
    "email_domains": [
      "asana.com"
    ],
    "is_organization": false
  }
}

Properties

Name Type Required Restrictions Description
data Workspace false none none

WorkspaceArray

{
  "data": [
    {
      "id": 12345,
      "gid": "12345",
      "resource_type": "task",
      "name": "Bug Task",
      "email_domains": [
        "asana.com"
      ],
      "is_organization": false
    }
  ]
}

Properties

Name Type Required Restrictions Description
data [Workspace] false none none